Fix: Use action_t in keymap files
[tmk_keyboard.git] / orphan / ghost_squid / matrix.c
CommitLineData
a6d33e2c
VO
1/*
2Copyright 2014 Ralf Schmitt <ralf@bunkertor.net>
3
4This program is free software: you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by
6the Free Software Foundation, either version 2 of the License, or
7(at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along 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
30static uint8_t debouncing = DEBOUNCE;
31
32static matrix_row_t matrix[MATRIX_ROWS];
33static matrix_row_t matrix_debouncing[MATRIX_ROWS];
34
35static uint8_t read_rows(void);
36static void init_rows(void);
37static void unselect_cols(void);
38static void select_col(uint8_t col);
39
40inline uint8_t matrix_rows(void)
41{
42 return MATRIX_ROWS;
43}
44
45inline uint8_t matrix_cols(void)
46{
47 return MATRIX_COLS;
48}
49
50void 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
60uint8_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
90bool matrix_is_modified(void)
91{
92 if (debouncing) return false;
93 return true;
94}
95
96inline bool matrix_is_on(uint8_t row, uint8_t col)
97{
98 return (matrix[row] & ((matrix_row_t)1<<col));
99}
100
101inline matrix_row_t matrix_get_row(uint8_t row)
102{
103 return matrix[row];
104}
105
106void 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
114uint8_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 */
129static void init_rows(void)
130{
131 DDRC &= ~0b00000100;
132 DDRB &= ~0b01111111;
133 PORTC |= 0b00000100;
134 PORTB |= 0b01111111;
135}
136
137static 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 */
173static void unselect_cols(void)
174{
175 DDRD |= 0b01111111;
176 PORTD &= ~0b01111111;
177}
178
179static 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