aboutsummaryrefslogtreecommitdiff
path: root/keyboard/planck/matrix.c
diff options
context:
space:
mode:
Diffstat (limited to 'keyboard/planck/matrix.c')
-rw-r--r--keyboard/planck/matrix.c235
1 files changed, 235 insertions, 0 deletions
diff --git a/keyboard/planck/matrix.c b/keyboard/planck/matrix.c
new file mode 100644
index 000000000..58bd61f75
--- /dev/null
+++ b/keyboard/planck/matrix.c
@@ -0,0 +1,235 @@
1/*
2Copyright 2012 Jun Wako
3Generated by planckkeyboard.com (2014 Jack Humbert)
4
5This program is free software: you can redistribute it and/or modify
6it under the terms of the GNU General Public License as published by
7the Free Software Foundation, either version 2 of the License, or
8(at your option) any later version.
9
10This program is distributed in the hope that it will be useful,
11but WITHOUT ANY WARRANTY; without even the implied warranty of
12MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with this program. If not, see <http://www.gnu.org/licenses/>.
17*/
18
19/*
20 * scan matrix
21 */
22#include <stdint.h>
23#include <stdbool.h>
24#include <avr/io.h>
25#include <util/delay.h>
26#include "print.h"
27#include "debug.h"
28#include "util.h"
29#include "matrix.h"
30#include "backlight.h" // TODO fix this dependency
31
32#ifndef DEBOUNCE
33# define DEBOUNCE 10
34#endif
35static uint8_t debouncing = DEBOUNCE;
36
37/* matrix state(1:on, 0:off) */
38static matrix_row_t matrix[MATRIX_ROWS];
39static matrix_row_t matrix_debouncing[MATRIX_ROWS];
40
41static matrix_row_t read_cols(void);
42static void init_cols(void);
43static void unselect_rows(void);
44static void select_row(uint8_t row);
45
46inline
47uint8_t matrix_rows(void)
48{
49 return MATRIX_ROWS;
50}
51
52inline
53uint8_t matrix_cols(void)
54{
55 return MATRIX_COLS;
56}
57
58void matrix_init(void)
59{
60 // To use PORTF disable JTAG with writing JTD bit twice within four cycles.
61 MCUCR |= (1<<JTD);
62 MCUCR |= (1<<JTD);
63
64 backlight_init_ports();
65
66 // Turn status LED on
67 DDRE |= (1<<6);
68 PORTE |= (1<<6);
69
70 // initialize row and col
71 unselect_rows();
72 init_cols();
73
74 // initialize matrix state: all keys off
75 for (uint8_t i=0; i < MATRIX_ROWS; i++) {
76 matrix[i] = 0;
77 matrix_debouncing[i] = 0;
78 }
79}
80
81
82uint8_t matrix_scan(void)
83{
84 for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
85 select_row(i);
86 _delay_us(30); // without this wait read unstable value.
87 matrix_row_t cols = read_cols();
88 if (matrix_debouncing[i] != cols) {
89 matrix_debouncing[i] = cols;
90 if (debouncing) {
91 debug("bounce!: "); debug_hex(debouncing); debug("\n");
92 }
93 debouncing = DEBOUNCE;
94 }
95 unselect_rows();
96 }
97
98 if (debouncing) {
99 if (--debouncing) {
100 _delay_ms(1);
101 } else {
102 for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
103 matrix[i] = matrix_debouncing[i];
104 }
105 }
106 }
107
108 return 1;
109}
110
111bool matrix_is_modified(void)
112{
113 if (debouncing) return false;
114 return true;
115}
116
117inline
118bool matrix_is_on(uint8_t row, uint8_t col)
119{
120 return (matrix[row] & ((matrix_row_t)1<col));
121}
122
123inline
124matrix_row_t matrix_get_row(uint8_t row)
125{
126 return matrix[row];
127}
128
129void matrix_print(void)
130{
131 print("\nr/c 0123456789ABCDEF\n");
132 for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
133 phex(row); print(": ");
134 pbin_reverse16(matrix_get_row(row));
135 print("\n");
136 }
137}
138
139uint8_t matrix_key_count(void)
140{
141 uint8_t count = 0;
142 for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
143 count += bitpop16(matrix[i]);
144 }
145 return count;
146}
147
148static void init_cols(void)
149{
150 int B = 0, C = 0, D = 0, E = 0, F = 0;
151 for(int x = 0; x < MATRIX_COLS; x++) {
152 int col = COLS[x];
153 if ((col & 0xF0) == 0x20) {
154 B |= (1<<(col & 0x0F));
155 } else if ((col & 0xF0) == 0x30) {
156 C |= (1<<(col & 0x0F));
157 } else if ((col & 0xF0) == 0x40) {
158 D |= (1<<(col & 0x0F));
159 } else if ((col & 0xF0) == 0x50) {
160 E |= (1<<(col & 0x0F));
161 } else if ((col & 0xF0) == 0x60) {
162 F |= (1<<(col & 0x0F));
163 }
164 }
165 DDRB &= ~(B); PORTB |= (B);
166 DDRC &= ~(C); PORTC |= (C);
167 DDRD &= ~(D); PORTD |= (D);
168 DDRE &= ~(E); PORTE |= (E);
169 DDRF &= ~(F); PORTF |= (F);
170}
171
172static matrix_row_t read_cols(void)
173{
174 matrix_row_t result = 0;
175 for(int x = 0; x < MATRIX_COLS; x++) {
176 int col = COLS[x];
177 if ((col & 0xF0) == 0x20) {
178 result |= (PINB&(1<<(col & 0x0F)) ? 0 : (1<<x));
179 } else if ((col & 0xF0) == 0x30) {
180 result |= (PINC&(1<<(col & 0x0F)) ? 0 : (1<<x));
181 } else if ((col & 0xF0) == 0x40) {
182 result |= (PIND&(1<<(col & 0x0F)) ? 0 : (1<<x));
183 } else if ((col & 0xF0) == 0x50) {
184 result |= (PINE&(1<<(col & 0x0F)) ? 0 : (1<<x));
185 } else if ((col & 0xF0) == 0x60) {
186 result |= (PINF&(1<<(col & 0x0F)) ? 0 : (1<<x));
187 }
188 }
189 return result;
190}
191
192static void unselect_rows(void)
193{
194 int B = 0, C = 0, D = 0, E = 0, F = 0;
195 for(int x = 0; x < MATRIX_ROWS; x++) {
196 int row = ROWS[x];
197 if ((row & 0xF0) == 0x20) {
198 B |= (1<<(row & 0x0F));
199 } else if ((row & 0xF0) == 0x30) {
200 C |= (1<<(row & 0x0F));
201 } else if ((row & 0xF0) == 0x40) {
202 D |= (1<<(row & 0x0F));
203 } else if ((row & 0xF0) == 0x50) {
204 E |= (1<<(row & 0x0F));
205 } else if ((row & 0xF0) == 0x60) {
206 F |= (1<<(row & 0x0F));
207 }
208 }
209 DDRB &= ~(B); PORTB |= (B);
210 DDRC &= ~(C); PORTC |= (C);
211 DDRD &= ~(D); PORTD |= (D);
212 DDRE &= ~(E); PORTE |= (E);
213 DDRF &= ~(F); PORTF |= (F);
214}
215
216static void select_row(uint8_t row)
217{
218 int row_pin = ROWS[row];
219 if ((row_pin & 0xF0) == 0x20) {
220 DDRB |= (1<<(row_pin & 0x0F));
221 PORTB &= ~(1<<(row_pin & 0x0F));
222 } else if ((row_pin & 0xF0) == 0x30) {
223 DDRC |= (1<<(row_pin & 0x0F));
224 PORTC &= ~(1<<(row_pin & 0x0F));
225 } else if ((row_pin & 0xF0) == 0x40) {
226 DDRD |= (1<<(row_pin & 0x0F));
227 PORTD &= ~(1<<(row_pin & 0x0F));
228 } else if ((row_pin & 0xF0) == 0x50) {
229 DDRE |= (1<<(row_pin & 0x0F));
230 PORTE &= ~(1<<(row_pin & 0x0F));
231 } else if ((row_pin & 0xF0) == 0x60) {
232 DDRF |= (1<<(row_pin & 0x0F));
233 PORTF &= ~(1<<(row_pin & 0x0F));
234 }
235} \ No newline at end of file