]>
Commit | Line | Data |
---|---|---|
083433b4 ES |
1 | /* |
2 | Copyright 2012 Jun Wako <wakojun@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 | ||
c8494e10 ES |
40 | static matrix_row_t matrix_reversed[MATRIX_COLS]; |
41 | static matrix_row_t matrix_reversed_debouncing[MATRIX_COLS]; | |
42 | ||
083433b4 ES |
43 | static matrix_row_t read_cols(void); |
44 | static void init_cols(void); | |
45 | static void unselect_rows(void); | |
46 | static void select_row(uint8_t row); | |
47 | ||
48 | ||
49 | inline | |
50 | uint8_t matrix_rows(void) | |
51 | { | |
52 | return MATRIX_ROWS; | |
53 | } | |
54 | ||
55 | inline | |
56 | uint8_t matrix_cols(void) | |
57 | { | |
58 | return MATRIX_COLS; | |
59 | } | |
60 | ||
61 | void matrix_init(void) | |
62 | { | |
63 | // To use PORTF disable JTAG with writing JTD bit twice within four cycles. | |
64 | MCUCR |= (1<<JTD); | |
65 | MCUCR |= (1<<JTD); | |
66 | ||
67 | // initialize row and col | |
68 | unselect_rows(); | |
69 | init_cols(); | |
70 | ||
71 | // initialize matrix state: all keys off | |
72 | for (uint8_t i=0; i < MATRIX_ROWS; i++) { | |
73 | matrix[i] = 0; | |
74 | matrix_debouncing[i] = 0; | |
75 | } | |
76 | } | |
77 | ||
78 | uint8_t matrix_scan(void) | |
79 | { | |
c8494e10 | 80 | for (uint8_t i = 0; i < MATRIX_COLS; i++) { |
083433b4 ES |
81 | select_row(i); |
82 | _delay_us(30); // without this wait read unstable value. | |
c8494e10 ES |
83 | matrix_row_t rows = read_cols(); |
84 | if (matrix_reversed_debouncing[i] != rows) { | |
85 | matrix_reversed_debouncing[i] = rows; | |
083433b4 ES |
86 | if (debouncing) { |
87 | debug("bounce!: "); debug_hex(debouncing); debug("\n"); | |
88 | } | |
89 | debouncing = DEBOUNCE; | |
90 | } | |
91 | unselect_rows(); | |
92 | } | |
93 | ||
94 | if (debouncing) { | |
95 | if (--debouncing) { | |
96 | _delay_ms(1); | |
97 | } else { | |
c8494e10 ES |
98 | for (uint8_t i = 0; i < MATRIX_COLS; i++) { |
99 | matrix_reversed[i] = matrix_reversed_debouncing[i]; | |
083433b4 ES |
100 | } |
101 | } | |
102 | } | |
103 | ||
c8494e10 ES |
104 | for (uint8_t y = 0; y < MATRIX_ROWS; y++) { |
105 | matrix_row_t row = 0; | |
106 | for (uint8_t x = 0; x < MATRIX_COLS; x++) { | |
107 | row |= ((matrix_reversed[x] & (1<<y)) >> y) << x; | |
108 | } | |
109 | matrix[y] = row; | |
110 | } | |
111 | ||
083433b4 ES |
112 | return 1; |
113 | } | |
114 | ||
115 | bool matrix_is_modified(void) | |
116 | { | |
117 | if (debouncing) return false; | |
118 | return true; | |
119 | } | |
120 | ||
121 | inline | |
122 | bool matrix_is_on(uint8_t row, uint8_t col) | |
123 | { | |
124 | return (matrix[row] & ((matrix_row_t)1<<col)); | |
125 | } | |
126 | ||
127 | inline | |
128 | matrix_row_t matrix_get_row(uint8_t row) | |
129 | { | |
130 | return matrix[row]; | |
131 | } | |
132 | ||
133 | void matrix_print(void) | |
134 | { | |
135 | print("\nr/c 0123456789ABCDEF\n"); | |
136 | for (uint8_t row = 0; row < MATRIX_ROWS; row++) { | |
137 | phex(row); print(": "); | |
138 | pbin_reverse16(matrix_get_row(row)); | |
139 | print("\n"); | |
140 | } | |
141 | } | |
142 | ||
143 | /* Column pin configuration | |
144 | * col: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 | |
145 | * pin: F0 F1 E6 C7 C6 B6 D4 B1 B0 B5 B4 D7 D6 B3 (Rev.A) | |
146 | * pin: B7 (Rev.B) | |
147 | */ | |
148 | static void init_cols(void) | |
149 | { | |
150 | // Input with pull-up(DDR:0, PORT:1) | |
c8494e10 ES |
151 | // DDRF &= ~(1<<0 | 1<<1 | 1<<4 | 1<<5); |
152 | // PORTF |= (1<<0 | 1<<1 | 1<<4 | 1<<5); | |
153 | // DDRD &= ~(1<<0 | 1<<1 | 1<<2 | 1<<3 | 1<<4 | 1<<5 | 1<<6 | 1<<7); | |
154 | // PORTD |= (1<<0 | 1<<1 | 1<<2 | 1<<3 | 1<<4 | 1<<5 | 1<<6 | 1<<7); | |
155 | // DDRB &= ~(1<<1 | 1<<3); | |
156 | // PORTB |= (1<<1 | 1<<3); | |
083433b4 | 157 | |
c8494e10 ES |
158 | DDRB &= ~(1<<0 | 1<<2 | 1<<4 | 1<<5 | 1<<6); |
159 | PORTB |= (1<<0 | 1<<2 | 1<<4 | 1<<5 | 1<<6); | |
083433b4 ES |
160 | } |
161 | ||
162 | static matrix_row_t read_cols(void) | |
163 | { | |
c8494e10 ES |
164 | // return (PINF&(1<<5) ? 0 : (1<<0)) | |
165 | // (PINB&(1<<1) ? 0 : (1<<1)) | | |
166 | // (PINF&(1<<0) ? 0 : (1<<2)) | | |
167 | // (PINF&(1<<1) ? 0 : (1<<3)) | | |
168 | // (PINF&(1<<4) ? 0 : (1<<4)) | | |
169 | // (PINB&(1<<3) ? 0 : (1<<5)) | | |
170 | // (PIND&(1<<7) ? 0 : (1<<6)) | | |
171 | // (PIND&(1<<6) ? 0 : (1<<7)) | | |
172 | // (PIND&(1<<4) ? 0 : (1<<8)) | | |
173 | // (PIND&(1<<5) ? 0 : (1<<9)) | | |
174 | // (PIND&(1<<3) ? 0 : (1<<10)) | | |
175 | // (PIND&(1<<2) ? 0 : (1<<11)) | | |
176 | // (PIND&(1<<1) ? 0 : (1<<12)) | | |
177 | // (PIND&(1<<0) ? 0 : (1<<13)); | |
083433b4 | 178 | |
c8494e10 ES |
179 | return (PINB&(1<<0) ? 0 : (1<<0)) | |
180 | (PINB&(1<<2) ? 0 : (1<<1)) | | |
181 | (PINB&(1<<4) ? 0 : (1<<2)) | | |
182 | (PINB&(1<<5) ? 0 : (1<<3)) | | |
183 | (PINB&(1<<6) ? 0 : (1<<4)); | |
083433b4 ES |
184 | } |
185 | ||
186 | /* Row pin configuration | |
187 | * row: 0 1 2 3 4 | |
188 | * pin: D0 D1 D2 D3 D5 | |
189 | */ | |
190 | static void unselect_rows(void) | |
191 | { | |
c8494e10 ES |
192 | // // Hi-Z(DDR:0, PORT:0) to unselect |
193 | // DDRB &= ~0b01110101; | |
194 | // PORTB &= ~0b01110101; | |
083433b4 | 195 | |
c8494e10 ES |
196 | DDRB &= ~0b00001010; |
197 | PORTB &= ~0b00001010; | |
198 | DDRD &= ~0b11111111; | |
199 | PORTD &= ~0b11111111; | |
200 | DDRF &= ~0b00110011; | |
201 | PORTF &= ~0b00110011; | |
083433b4 ES |
202 | } |
203 | ||
204 | static void select_row(uint8_t row) | |
205 | { | |
206 | // Output low(DDR:1, PORT:0) to select | |
c8494e10 ES |
207 | // switch (row) { |
208 | // case 0: | |
209 | // DDRB |= (1<<0); | |
210 | // PORTB &= ~(1<<0); | |
211 | // break; | |
212 | // case 1: | |
213 | // DDRB |= (1<<2); | |
214 | // PORTB &= ~(1<<2); | |
215 | // break; | |
216 | // case 2: | |
217 | // DDRB |= (1<<4); | |
218 | // PORTB &= ~(1<<4); | |
219 | // break; | |
220 | // case 3: | |
221 | // DDRB |= (1<<5); | |
222 | // PORTB &= ~(1<<5); | |
223 | // break; | |
224 | // case 4: | |
225 | // DDRB |= (1<<6); | |
226 | // PORTB &= ~(1<<6); | |
227 | // break; | |
228 | // } | |
229 | ||
230 | switch (row) { | |
231 | case 0: | |
232 | DDRF |= (1<<5); | |
233 | PORTF &= ~(1<<5); | |
234 | break; | |
235 | case 1: | |
236 | DDRB |= (1<<1); | |
237 | PORTB &= ~(1<<1); | |
238 | break; | |
239 | case 2: | |
240 | DDRF |= (1<<0); | |
241 | PORTF &= ~(1<<0); | |
242 | break; | |
243 | case 3: | |
244 | DDRF |= (1<<1); | |
245 | PORTF &= ~(1<<1); | |
246 | break; | |
247 | case 4: | |
248 | DDRF |= (1<<4); | |
249 | PORTF &= ~(1<<4); | |
250 | break; | |
251 | case 5: | |
252 | DDRB |= (1<<3); | |
253 | PORTB &= ~(1<<3); | |
254 | break; | |
255 | case 6: | |
256 | DDRD |= (1<<7); | |
257 | PORTD &= ~(1<<7); | |
258 | break; | |
259 | case 7: | |
260 | DDRD |= (1<<6); | |
261 | PORTD &= ~(1<<6); | |
262 | break; | |
263 | case 8: | |
264 | DDRD |= (1<<4); | |
265 | PORTD &= ~(1<<4); | |
266 | break; | |
267 | case 9: | |
268 | DDRD |= (1<<5); | |
269 | PORTD &= ~(1<<5); | |
270 | break; | |
271 | case 10: | |
272 | DDRD |= (1<<3); | |
273 | PORTD &= ~(1<<3); | |
274 | break; | |
275 | case 11: | |
276 | DDRD |= (1<<2); | |
277 | PORTD &= ~(1<<2); | |
278 | break; | |
279 | case 12: | |
280 | DDRD |= (1<<1); | |
281 | PORTD &= ~(1<<1); | |
282 | break; | |
283 | case 13: | |
284 | DDRD |= (1<<0); | |
285 | PORTD &= ~(1<<0); | |
286 | } | |
083433b4 | 287 | } |