]> git.gir.st - tmk_keyboard.git/blob - keyboard/ghost_squid/matrix.c
Merge branch 'remote_wakeup_32u2_fix'
[tmk_keyboard.git] / keyboard / ghost_squid / matrix.c
1 /*
2 Copyright 2014 Ralf Schmitt <ralf@bunkertor.net>
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 #include <stdint.h>
19 #include <stdbool.h>
20 #include <avr/io.h>
21 #include <util/delay.h>
22 #include "print.h"
23 #include "debug.h"
24 #include "util.h"
25 #include "matrix.h"
26
27 #ifndef DEBOUNCE
28 # define DEBOUNCE 0
29 #endif
30 static uint8_t debouncing = DEBOUNCE;
31
32 static matrix_row_t matrix[MATRIX_ROWS];
33 static matrix_row_t matrix_debouncing[MATRIX_ROWS];
34
35 static uint8_t read_rows(void);
36 static void init_rows(void);
37 static void unselect_cols(void);
38 static void select_col(uint8_t col);
39
40 inline uint8_t matrix_rows(void)
41 {
42 return MATRIX_ROWS;
43 }
44
45 inline uint8_t matrix_cols(void)
46 {
47 return MATRIX_COLS;
48 }
49
50 void matrix_init(void)
51 {
52 unselect_cols();
53 init_rows();
54 for (uint8_t i=0; i < MATRIX_ROWS; i++) {
55 matrix[i] = 0;
56 matrix_debouncing[i] = 0;
57 }
58 }
59
60 uint8_t matrix_scan(void)
61 {
62 for (uint8_t col = 0; col < MATRIX_COLS; col++) {
63 select_col(col);
64 _delay_us(3);
65 uint8_t rows = read_rows();
66 for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
67 bool prev_bit = matrix_debouncing[row] & ((matrix_row_t)1<<col);
68 bool curr_bit = rows & (1<<row);
69 if (prev_bit != curr_bit) {
70 matrix_debouncing[row] ^= ((matrix_row_t)1<<col);
71 debouncing = DEBOUNCE;
72 }
73 }
74 unselect_cols();
75 }
76
77 if (debouncing) {
78 if (--debouncing) {
79 _delay_ms(1);
80 } else {
81 for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
82 matrix[i] = matrix_debouncing[i];
83 }
84 }
85 }
86
87 return 1;
88 }
89
90 bool matrix_is_modified(void)
91 {
92 if (debouncing) return false;
93 return true;
94 }
95
96 inline bool matrix_is_on(uint8_t row, uint8_t col)
97 {
98 return (matrix[row] & ((matrix_row_t)1<<col));
99 }
100
101 inline matrix_row_t matrix_get_row(uint8_t row)
102 {
103 return matrix[row];
104 }
105
106 void matrix_print(void)
107 {
108 print("\nr/c 0123456789ABCDEF\n");
109 for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
110 xprintf("%02X: %032lb\n", row, bitrev32(matrix_get_row(row)));
111 }
112 }
113
114 uint8_t matrix_key_count(void)
115 {
116 uint8_t count = 0;
117 for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
118 count += bitpop32(matrix[i]);
119 }
120 return count;
121 }
122
123 /* Row pin configuration
124 *
125 * row: 0 1 2 3 4 5 6 7
126 * pin: PB1 PC2 PB6 PB4 PB3 PB5 PB0 PB2
127 *
128 */
129 static void init_rows(void)
130 {
131 DDRC &= ~0b00000100;
132 DDRB &= ~0b01111111;
133 PORTC |= 0b00000100;
134 PORTB |= 0b01111111;
135 }
136
137 static uint8_t read_rows(void)
138 {
139 return (PINB&(1<<1) ? 0 : (1<<0)) |
140 (PINC&(1<<2) ? 0 : (1<<1)) |
141 (PINB&(1<<6) ? 0 : (1<<2)) |
142 (PINB&(1<<4) ? 0 : (1<<3)) |
143 (PINB&(1<<3) ? 0 : (1<<4)) |
144 (PINB&(1<<5) ? 0 : (1<<5)) |
145 (PINB&(1<<0) ? 0 : (1<<6)) |
146 (PINB&(1<<2) ? 0 : (1<<7));
147 }
148
149 /* These columns uses two 74HC42 4 to 10 bit demultiplexers (low active).
150 *
151 * COL PD6 PD5 PD4 PD3 PD2 PD1
152 * 10 1 1 0 0 0 0
153 * 15 1 1 0 0 0 1
154 * 8 1 1 0 0 1 0
155 * 14 1 1 0 1 0 0
156 * 6 1 1 0 1 0 1
157 * 13 1 1 0 1 1 0
158 * 12 1 1 1 0 0 0
159 * 9 1 1 1 0 1 0
160 * 11 1 1 1 1 0 0
161 * 7 1 1 1 1 1 0
162 *
163 * COL PD1 PD2 PD3 PD4 PD5 PD6
164 * 3 1 1 0 0 0 1
165 * 4 1 1 0 0 1 0
166 * 17 1 1 0 1 0 0
167 * 16 1 1 0 1 1 0
168 * 0 1 1 1 0 0 1
169 * 5 1 1 1 0 1 0
170 * 2 1 1 1 1 0 0
171 * 1 1 1 1 1 1 0
172 */
173 static void unselect_cols(void)
174 {
175 DDRD |= 0b01111111;
176 PORTD &= ~0b01111111;
177 }
178
179 static void select_col(uint8_t col)
180 {
181 switch (col) {
182 case 0:
183 PORTD |= (1<<6) | (1<<3) | (1<<2) | (1<<1);
184 break;
185 case 1:
186 PORTD |= (1<<5) | (1<<4) | (1<<3) | (1<<2) | (1<<1);
187 break;
188 case 2:
189 PORTD |= (1<<4) | (1<<3) | (1<<2) | (1<<1);
190 break;
191 case 3:
192 PORTD |= (1<<6) | (1<<2) | (1<<1);
193 break;
194 case 4:
195 PORTD |= (1<<5) | (1<<2) | (1<<1);
196 break;
197 case 5:
198 PORTD |= (1<<5) | (1<<3) | (1<<2) | (1<<1);
199 break;
200 case 6:
201 PORTD |= (1<<6) | (1<<5) | (1<<3) | (1<<1);
202 break;
203 case 7:
204 PORTD |= (1<<6) | (1<<5) | (1<<4) | (1<<3) | (1<<2);
205 break;
206 case 8:
207 PORTD |= (1<<6) | (1<<5) | (1<<2);
208 break;
209 case 9:
210 PORTD |= (1<<6) | (1<<5) | (1<<4) | (1<<2);
211 break;
212 case 10:
213 PORTD |= (1<<6) | (1<<5);
214 break;
215 case 11:
216 PORTD |= (1<<6) | (1<<5) | (1<<4) | (1<<3);
217 break;
218 case 12:
219 PORTD |= (1<<6) | (1<<5) | (1<<4);
220 break;
221 case 13:
222 PORTD |= (1<<6) | (1<<5) | (1<<3) | (1<<2);
223 break;
224 case 14:
225 PORTD |= (1<<6) | (1<<5) | (1<<3);
226 break;
227 case 15:
228 PORTD |= (1<<6) | (1<<5) | (1<<1);
229 break;
230 case 16:
231 PORTD |= (1<<5) | (1<<4) | (1<<2) | (1<<1);
232 break;
233 case 17:
234 PORTD |= (1<<4) | (1<<2) | (1<<1);
235 break;
236 }
237 }
Imprint / Impressum