]> git.gir.st - tmk_keyboard.git/blob - macway/matrix.c
new build method for macway
[tmk_keyboard.git] / macway / matrix.c
1 /*
2 * scan matrix
3 */
4 #include <stdint.h>
5 #include <stdbool.h>
6 #include <avr/io.h>
7 #include <util/delay.h>
8 #include "matrix.h"
9 #include "print.h"
10 #include "util.h"
11
12 // matrix is active low. (key on: 0/key off: 1)
13 // row: Hi-Z(unselected)/low output(selected)
14 // PD0, PC7, PD7, PF6, PD6, PD1, PD2, PC6, PF7
15 // col: input w/pullup
16 // PB0-PB7
17
18 // matrix state buffer
19 uint8_t *matrix;
20 uint8_t *matrix_prev;
21 static uint8_t _matrix0[MATRIX_ROWS];
22 static uint8_t _matrix1[MATRIX_ROWS];
23
24 static bool matrix_has_ghost_in_row(uint8_t row);
25 static uint8_t read_col(void);
26 static void unselect_rows(void);
27 static void select_row(uint8_t row);
28
29
30 inline
31 int matrix_rows(void)
32 {
33 return MATRIX_ROWS;
34 }
35
36 inline
37 int matrix_cols(void)
38 {
39 return MATRIX_COLS;
40 }
41
42 // this must be called once before matrix_scan.
43 void matrix_init(void)
44 {
45 // initialize row and col
46 unselect_rows();
47 DDRB = 0x00;
48 PORTB = 0xFF;
49
50 // initialize matrix state: all keys off
51 for (int i=0; i < MATRIX_ROWS; i++) _matrix0[i] = 0x00;
52 for (int i=0; i < MATRIX_ROWS; i++) _matrix1[i] = 0x00;
53 matrix = _matrix0;
54 matrix_prev = _matrix1;
55 }
56
57 int matrix_scan(void)
58 {
59 uint8_t *tmp;
60
61 tmp = matrix_prev;
62 matrix_prev = matrix;
63 matrix = tmp;
64
65 for (int i = 0; i < MATRIX_ROWS; i++) {
66 select_row(i);
67 _delay_us(30); // without this wait read unstable value.
68 matrix[i] = ~read_col();
69 unselect_rows();
70 }
71 return 1;
72 }
73
74 bool matrix_is_modified(void)
75 {
76 for (int i = 0; i < MATRIX_ROWS; i++) {
77 if (matrix[i] != matrix_prev[i])
78 return true;
79 }
80 return false;
81 }
82
83 bool matrix_has_ghost(void)
84 {
85 for (int i = 0; i < MATRIX_ROWS; i++) {
86 if (matrix_has_ghost_in_row(i))
87 return true;
88 }
89 return false;
90 }
91
92 inline
93 bool matrix_is_on(int row, int col)
94 {
95 return (matrix[row] & (1<<col));
96 }
97
98 inline
99 uint16_t matrix_get_row(int row)
100 {
101 return matrix[row];
102 }
103
104 void matrix_print(void)
105 {
106 print("\nr/c 01234567\n");
107 for (int row = 0; row < matrix_rows(); row++) {
108 phex(row); print(": ");
109 pbin_reverse(matrix_get_row(row));
110 if (matrix_has_ghost_in_row(row)) {
111 print(" <ghost");
112 }
113 print("\n");
114 }
115 }
116
117 int matrix_key_count(void)
118 {
119 int count = 0;
120 for (int i = 0; i < MATRIX_ROWS; i++) {
121 count += bitpop(matrix[i]);
122 }
123 return count;
124 }
125
126 static bool matrix_has_ghost_in_row(uint8_t row)
127 {
128 // no ghost exists in case less than 2 keys on
129 if (((matrix[row] - 1) & matrix[row]) == 0)
130 return false;
131
132 // ghost exists in case same state as other row
133 for (int i=0; i < MATRIX_ROWS; i++) {
134 if (i != row && (matrix[i] & matrix[row]) == matrix[row])
135 return true;
136 }
137 return false;
138 }
139
140 static uint8_t read_col(void)
141 {
142 return PINB;
143 }
144
145 static void unselect_rows(void)
146 {
147 DDRD = 0x00;
148 PORTD = 0x00;
149 DDRC = 0x00;
150 PORTC = 0x00;
151 DDRF = 0x00;
152 PORTF = 0x00;
153 }
154
155 static void select_row(uint8_t row)
156 {
157 switch (row) {
158 case 0:
159 DDRD = (1<<0);
160 PORTD = 0x00;
161 DDRC = 0x00;
162 PORTC = 0x00;
163 DDRF = 0x00;
164 PORTF = 0x00;
165 break;
166 case 1:
167 DDRD = 0x00;
168 PORTD = 0x00;
169 DDRC = (1<<7);
170 PORTC = 0x00;
171 DDRF = 0x00;
172 PORTF = 0x00;
173 break;
174 case 2:
175 DDRD = (1<<7);
176 PORTD = 0x00;
177 DDRC = 0x00;
178 PORTC = 0x00;
179 DDRF = 0x00;
180 PORTF = 0x00;
181 break;
182 case 3:
183 DDRD = 0x00;
184 PORTD = 0x00;
185 DDRC = 0x00;
186 PORTC = 0x00;
187 DDRF = (1<<6);
188 PORTF = 0x00;
189 break;
190 case 4:
191 DDRD = (1<<6);
192 PORTD = 0x00;
193 DDRC = 0x00;
194 PORTC = 0x00;
195 DDRF = 0x00;
196 PORTF = 0x00;
197 break;
198 case 5:
199 DDRD = (1<<1);
200 PORTD = 0x00;
201 DDRC = 0x00;
202 PORTC = 0x00;
203 DDRF = 0x00;
204 PORTF = 0x00;
205 break;
206 case 6:
207 DDRD = (1<<2);
208 PORTD = 0x00;
209 DDRC = 0x00;
210 PORTC = 0x00;
211 DDRF = 0x00;
212 PORTF = 0x00;
213 break;
214 case 7:
215 DDRD = 0x00;
216 PORTD = 0x00;
217 DDRC = (1<<6);
218 PORTC = 0x00;
219 DDRF = 0x00;
220 PORTF = 0x00;
221 break;
222 case 8:
223 DDRD = 0x00;
224 PORTD = 0x00;
225 DDRC = 0x00;
226 PORTC = 0x00;
227 DDRF = (1<<7);
228 PORTF = 0x00;
229 break;
230 }
231 }
Imprint / Impressum