]> git.gir.st - tmk_keyboard.git/blob - keyboard/minorca/matrix.c
more on layer2, moved around fn-actions
[tmk_keyboard.git] / keyboard / minorca / matrix.c
1 /*
2 Copyright 2012 Jun Wako <wakojun@gmail.com>
3 This program is free software: you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation, either version 2 of the License, or
6 (at your option) any later version.
7 This program is distributed in the hope that it will be useful,
8 but WITHOUT ANY WARRANTY; without even the implied warranty of
9 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 GNU General Public License for more details.
11 You should have received a copy of the GNU General Public License
12 along with this program. If not, see <http://www.gnu.org/licenses/>.
13 */
14
15 /*
16 * scan matrix
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
28 #ifndef DEBOUNCE
29 # define DEBOUNCE 5
30 #endif
31 static uint8_t debouncing = DEBOUNCE;
32
33 /* matrix state(1:on, 0:off) */
34 static matrix_row_t matrix[MATRIX_ROWS];
35 static matrix_row_t matrix_debouncing[MATRIX_ROWS];
36
37 static matrix_row_t read_cols(void);
38 static void init_cols(void);
39 static void unselect_rows(void);
40 static void select_row(uint8_t row);
41
42
43 inline
44 uint8_t matrix_rows(void)
45 {
46 return MATRIX_ROWS;
47 }
48
49 inline
50 uint8_t matrix_cols(void)
51 {
52 return MATRIX_COLS;
53 }
54
55 void matrix_init(void)
56 {
57 // initialize row and col
58 unselect_rows();
59 init_cols();
60
61 // initialize matrix state: all keys off
62 for (uint8_t i=0; i < MATRIX_ROWS; i++) {
63 matrix[i] = 0;
64 matrix_debouncing[i] = 0;
65 }
66 }
67
68 uint8_t matrix_scan(void)
69 {
70 for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
71 select_row(i);
72 _delay_us(30); // without this wait read unstable value.
73 matrix_row_t cols = read_cols();
74 if (matrix_debouncing[i] != cols) {
75 matrix_debouncing[i] = cols;
76 if (debouncing) {
77 debug("bounce!: "); debug_hex(debouncing); debug("\n");
78 }
79 debouncing = DEBOUNCE;
80 }
81 unselect_rows();
82 }
83
84 if (debouncing) {
85 if (--debouncing) {
86 _delay_ms(1);
87 } else {
88 for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
89 matrix[i] = matrix_debouncing[i];
90 }
91 }
92 }
93
94 return 1;
95 }
96
97 bool matrix_is_modified(void)
98 {
99 if (debouncing) return false;
100 return true;
101 }
102
103 inline
104 bool matrix_is_on(uint8_t row, uint8_t col)
105 {
106 return (matrix[row] & ((matrix_row_t)1<<col));
107 }
108
109 inline
110 matrix_row_t matrix_get_row(uint8_t row)
111 {
112 return matrix[row];
113 }
114
115 void matrix_print(void)
116 {
117 print("\nr/c 0123456789ABCDEF\n");
118 for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
119 phex(row); print(": ");
120 pbin_reverse16(matrix_get_row(row));
121 print("\n");
122 }
123 }
124
125 uint8_t matrix_key_count(void)
126 {
127 uint8_t count = 0;
128 for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
129 count += bitpop16(matrix[i]);
130 }
131 return count;
132 }
133
134 /* Column pin configuration
135 * col: 0 1 2 3 4 5 6 7 8 9 10 11
136 * pin: F6 F7 B6 B5 B4 D7 C7 C6 D3 D2 D1 D0
137 */
138 static void init_cols(void)
139 {
140 // Input with pull-up(DDR:0, PORT:1)
141 DDRF &= ~(1<<6 | 1<<7);
142 PORTF |= (1<<6 | 1<<7);
143 DDRB &= ~(1<<7 | 1<<6 | 1<< 5 | 1<<4);
144 PORTB |= (1<<6 | 1<<5 | 1<<4);
145 DDRD &= ~(1<<7 | 1<<3 | 1<<2| 1<<1 | 1<<0 );
146 PORTD |= (1<<7 | 1<<3 | 1<<2| 1<<1 | 1<<0 );
147 DDRC &= ~(1<<7 | 1<<6);
148 PORTC |= (1<<7 | 1<<6);
149 }
150
151 static matrix_row_t read_cols(void)
152 {
153 return (PINF&(1<<6) ? 0 : (1<<0)) |
154 (PINF&(1<<7) ? 0 : (1<<1)) |
155 (PINB&(1<<6) ? 0 : (1<<2)) |
156 (PINB&(1<<5) ? 0 : (1<<3)) |
157 (PINB&(1<<4) ? 0 : (1<<4)) |
158 (PIND&(1<<7) ? 0 : (1<<5)) |
159 (PINC&(1<<7) ? 0 : (1<<6)) |
160 (PINC&(1<<6) ? 0 : (1<<7)) |
161 (PIND&(1<<3) ? 0 : (1<<8)) |
162 (PIND&(1<<2) ? 0 : (1<<9)) |
163 (PIND&(1<<1) ? 0 : (1<<10)) |
164 (PIND&(1<<0) ? 0 : (1<<11)) ;
165 }
166
167 /* Row pin configuration
168 * row: 0 1 2 3
169 * pin: F0 F1 F4 F5
170 */
171 static void unselect_rows(void)
172 {
173 // Hi-Z(DDR:0, PORT:0) to unselect
174 DDRF &= ~0b00110011;
175 PORTF &= ~0b00110011;
176 }
177
178 static void select_row(uint8_t row)
179 {
180 // Output low(DDR:1, PORT:0) to select
181 switch (row) {
182 case 0:
183 DDRF |= (1<<0);
184 PORTF &= ~(1<<0);
185 break;
186 case 1:
187 DDRF |= (1<<1);
188 PORTF &= ~(1<<1);
189 break;
190 case 2:
191 DDRF |= (1<<4);
192 PORTF &= ~(1<<4);
193 break;
194 case 3:
195 DDRF |= (1<<5);
196 PORTF &= ~(1<<5);
197 break;
198 }
199 }
Imprint / Impressum