]> git.gir.st - tmk_keyboard.git/blob - orphan/kitten_paw/matrix.c
Merge branch 'orphans'
[tmk_keyboard.git] / orphan / kitten_paw / 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: PC2 PB1 PB2 PB3 PC7 PB4 PB5 PB6
127 *
128 */
129 static void init_rows(void)
130 {
131 DDRC &= ~0b10000100;
132 DDRB &= ~0b01111110;
133 PORTC |= 0b10000100;
134 PORTB |= 0b01111110;
135 }
136
137 static uint8_t read_rows(void)
138 {
139 return (PINC&(1<<2) ? 0 : (1<<0)) |
140 (PINB&(1<<1) ? 0 : (1<<1)) |
141 (PINB&(1<<2) ? 0 : (1<<2)) |
142 (PINB&(1<<3) ? 0 : (1<<3)) |
143 (PINC&(1<<7) ? 0 : (1<<4)) |
144 (PINB&(1<<4) ? 0 : (1<<5)) |
145 (PINB&(1<<5) ? 0 : (1<<6)) |
146 (PINB&(1<<6) ? 0 : (1<<7));
147 }
148
149 /* These columns uses two 74HC42 4 to 10 bit demultiplexers (low active).
150 *
151 * COL PD1 PD0 PD2 PD6 PD5 PD4
152 * 12 1 1 0 0 0 0
153 * 11 1 1 0 0 0 1
154 * 10 1 1 0 0 1 0
155 * 9 1 1 0 0 1 1
156 * 8 1 1 0 1 0 0
157 * 7 1 1 0 1 0 1
158 * 6 1 1 0 1 1 0
159 * 5 1 1 0 1 1 1
160 * 4 1 1 1 0 0 0
161 * 3 1 1 1 0 0 1
162
163 * COL PD2 PD6 PD1 PD0 PD5 PD4
164 * 2 1 1 0 0 0 0
165 * 1 1 1 0 0 0 1
166 * 0 1 1 0 0 1 0
167 * 17 1 1 0 0 1 1
168 * 16 1 1 0 1 0 0
169 * 1 1 0 1 0 1
170 * 1 1 0 1 1 0
171 * 15 1 1 0 1 1 1
172 * 14 1 1 1 0 0 0
173 * 13 1 1 1 0 0 1
174 */
175 static void unselect_cols(void)
176 {
177 DDRD |= 0b01110111;
178 PORTD &= ~0b01110111;
179 }
180
181 static void select_col(uint8_t col)
182 {
183 switch (col) {
184 case 0:
185 PORTD |= (1<<5) | (1<<6) | (1<<2);
186 break;
187 case 1:
188 PORTD |= (1<<4) | (1<<6) | (1<<2);
189 break;
190 case 2:
191 PORTD |= (1<<6) | (1<<2);
192 break;
193 case 3:
194 PORTD |= (1<<4) | (1<<2) | (1<<0) | (1<<1);
195 break;
196 case 4:
197 PORTD |= (1<<2) | (1<<0) | (1<<1);
198 break;
199 case 5:
200 PORTD |= (1<<4) | (1<<5) | (1<<6) | (1<<0) | (1<<1);
201 break;
202 case 6:
203 PORTD |= (1<<5) | (1<<6) | (1<<0) | (1<<1);
204 break;
205 case 7:
206 PORTD |= (1<<4) | (1<<6) | (1<<0) | (1<<1);
207 break;
208 case 8:
209 PORTD |= (1<<6) | (1<<0) | (1<<1);
210 break;
211 case 9:
212 PORTD |= (1<<4) | (1<<5) | (1<<0) | (1<<1);
213 break;
214 case 10:
215 PORTD |= (1<<5) | (1<<0) | (1<<1);
216 break;
217 case 11:
218 PORTD |= (1<<4) | (1<<0) | (1<<1);
219 break;
220 case 12:
221 PORTD |= (1<<0) | (1<<1);
222 break;
223 case 13:
224 PORTD |= (1<<4) | (1<<1) | (1<<6) | (1<<2);
225 break;
226 case 14:
227 PORTD |= (1<<1) | (1<<6) | (1<<2);
228 break;
229 case 15:
230 PORTD |= (1<<4) | (1<<5) | (1<<0) | (1<<6) | (1<<2);
231 break;
232 case 16:
233 PORTD |= (1<<0) | (1<<6) | (1<<2);
234 break;
235 case 17:
236 PORTD |= (1<<4) | (1<<5) | (1<<6) | (1<<2);
237 break;
238 }
239 }
Imprint / Impressum