aboutsummaryrefslogtreecommitdiff
path: root/keyboards/kmac/matrix.c
diff options
context:
space:
mode:
Diffstat (limited to 'keyboards/kmac/matrix.c')
-rw-r--r--keyboards/kmac/matrix.c359
1 files changed, 134 insertions, 225 deletions
diff --git a/keyboards/kmac/matrix.c b/keyboards/kmac/matrix.c
index 00da96604..2212ee076 100644
--- a/keyboards/kmac/matrix.c
+++ b/keyboards/kmac/matrix.c
@@ -1,5 +1,5 @@
1/* 1/*
2Copyright 2017 Mathias Andersson <wraul@dbox.se> 2Copyright 2017-2019 Mathias Andersson <wraul@dbox.se>
3 3
4This program is free software: you can redistribute it and/or modify 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 5it under the terms of the GNU General Public License as published by
@@ -16,118 +16,137 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
16*/ 16*/
17#include <stdint.h> 17#include <stdint.h>
18#include <stdbool.h> 18#include <stdbool.h>
19#if defined(__AVR__)
20#include <avr/io.h>
21#endif
22#include "wait.h" 19#include "wait.h"
23#include "print.h" 20#include "print.h"
24#include "debug.h" 21#include "debug.h"
25#include "util.h" 22#include "util.h"
26#include "matrix.h" 23#include "matrix.h"
27#include "timer.h" 24#include "debounce.h"
28 25#include "quantum.h"
29 26
30/* Set 0 if debouncing isn't needed */ 27#if (MATRIX_COLS <= 8)
31#ifndef DEBOUNCE 28# define print_matrix_header() print("\nr/c 01234567\n")
32# define DEBOUNCE 5 29# define print_matrix_row(row) print_bin_reverse8(matrix_get_row(row))
30# define matrix_bitpop(i) bitpop(matrix[i])
31# define ROW_SHIFTER ((uint8_t)1)
32#elif (MATRIX_COLS <= 16)
33# define print_matrix_header() print("\nr/c 0123456789ABCDEF\n")
34# define print_matrix_row(row) print_bin_reverse16(matrix_get_row(row))
35# define matrix_bitpop(i) bitpop16(matrix[i])
36# define ROW_SHIFTER ((uint16_t)1)
37#elif (MATRIX_COLS <= 32)
38# define print_matrix_header() print("\nr/c 0123456789ABCDEF0123456789ABCDEF\n")
39# define print_matrix_row(row) print_bin_reverse32(matrix_get_row(row))
40# define matrix_bitpop(i) bitpop32(matrix[i])
41# define ROW_SHIFTER ((uint32_t)1)
33#endif 42#endif
34 43
35#define COL_SHIFTER ((uint32_t)1) 44static const pin_t row_pins[MATRIX_ROWS] = MATRIX_ROW_PINS;
36 45static const pin_t col_pins[MATRIX_COLS] = MATRIX_COL_PINS;
37static uint16_t debouncing_time;
38static bool debouncing = false;
39
40
41static const uint8_t row_pins[MATRIX_ROWS] = MATRIX_ROW_PINS;
42 46
43/* matrix state(1:on, 0:off) */ 47/* matrix state(1:on, 0:off) */
44static matrix_row_t matrix[MATRIX_ROWS]; 48static matrix_row_t raw_matrix[MATRIX_ROWS]; // raw values
45static matrix_row_t matrix_debouncing[MATRIX_ROWS]; 49static matrix_row_t matrix[MATRIX_ROWS]; // debounced values
46 50
47static void init_rows(void); 51__attribute__((weak)) void matrix_init_quantum(void) { matrix_init_kb(); }
48static bool read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col);
49static void unselect_cols(void);
50static void select_col(uint8_t col);
51 52
52inline 53__attribute__((weak)) void matrix_scan_quantum(void) { matrix_scan_kb(); }
53uint8_t matrix_rows(void) {
54 return MATRIX_ROWS;
55}
56 54
57inline 55__attribute__((weak)) void matrix_init_kb(void) { matrix_init_user(); }
58uint8_t matrix_cols(void) {
59 return MATRIX_COLS;
60}
61 56
62void matrix_init(void) { 57__attribute__((weak)) void matrix_scan_kb(void) { matrix_scan_user(); }
63 unselect_cols();
64 init_rows();
65 58
66 // initialize matrix state: all keys off 59__attribute__((weak)) void matrix_init_user(void) {}
67 for (uint8_t i=0; i < MATRIX_ROWS; i++) {
68 matrix[i] = 0;
69 matrix_debouncing[i] = 0;
70 }
71 60
72 matrix_init_quantum(); 61__attribute__((weak)) void matrix_scan_user(void) {}
73}
74 62
75uint8_t matrix_scan(void) 63inline uint8_t matrix_rows(void) { return MATRIX_ROWS; }
76{
77 // Set col, read rows
78 for (uint8_t current_col = 0; current_col < MATRIX_COLS; current_col++) {
79 bool matrix_changed = read_rows_on_col(matrix_debouncing, current_col);
80 if (matrix_changed) {
81 debouncing = true;
82 debouncing_time = timer_read();
83 }
84 }
85
86 if (debouncing && (timer_elapsed(debouncing_time) > DEBOUNCE)) {
87 for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
88 matrix[i] = matrix_debouncing[i];
89 }
90 debouncing = false;
91 }
92 64
93 matrix_scan_quantum(); 65inline uint8_t matrix_cols(void) { return MATRIX_COLS; }
94 return 1;
95}
96 66
97inline 67inline bool matrix_is_on(uint8_t row, uint8_t col) { return (matrix[row] & ((matrix_row_t)1 << col)); }
98bool matrix_is_on(uint8_t row, uint8_t col)
99{
100 return (matrix[row] & ((matrix_row_t)1<<col));
101}
102 68
103inline 69inline matrix_row_t matrix_get_row(uint8_t row) { return matrix[row]; }
104matrix_row_t matrix_get_row(uint8_t row)
105{
106 return matrix[row];
107}
108 70
109void matrix_print(void) 71void matrix_print(void) {
110{ 72 print_matrix_header();
111 print("\nr/c 0123456789ABCDEFGHIJKLMNOPQRSTUV\n");
112 73
113 for (uint8_t row = 0; row < MATRIX_ROWS; row++) { 74 for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
114 phex(row); print(": "); 75 phex(row);
115 print_bin_reverse32(matrix_get_row(row)); 76 print(": ");
77 print_matrix_row(row);
116 print("\n"); 78 print("\n");
117 } 79 }
118} 80}
119 81
120uint8_t matrix_key_count(void) 82uint8_t matrix_key_count(void) {
121{
122 uint8_t count = 0; 83 uint8_t count = 0;
123 for (uint8_t i = 0; i < MATRIX_ROWS; i++) { 84 for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
124 count += bitpop32(matrix[i]); 85 count += matrix_bitpop(i);
125 } 86 }
126 return count; 87 return count;
127} 88}
128 89
129static bool read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col) 90/* Columns 0 - 15
130{ 91 * These columns uses two 74HC237D 3 to 8 bit demultiplexers.
92 * col / pin: PB6 PC6 PC7 PF1 PF0
93 * 0: 0 1 0 0 0
94 * 1: 0 1 0 0 1
95 * 2: 0 1 0 1 0
96 * 3: 0 1 0 1 1
97 * 4: 0 1 1 0 0
98 * 5: 0 1 1 0 1
99 * 6: 0 1 1 1 0
100 * 7: 0 1 1 1 1
101 * 8: 1 0 0 0 0
102 * 9: 1 0 0 0 1
103 * 10: 1 0 0 1 0
104 * 11: 1 0 0 1 1
105 * 12: 1 0 1 0 0
106 * 13: 1 0 1 0 1
107 * 14: 1 0 1 1 0
108 * 15: 1 0 1 1 1
109 *
110 * col: 16
111 * pin: PB5
112 */
113static void unselect_cols(void) {
114 for (uint8_t x = 0; x < 6; x++) {
115 setPinOutput(col_pins[x]);
116 writePinLow(col_pins[x]);
117 }
118}
119
120static void select_col(uint8_t col) {
121 if (col < 16) {
122 uint8_t c = col + 8;
123
124 writePin(B6, c & 0b10000);
125 writePin(C6, c & 0b01000);
126 writePin(C7, c & 0b00100);
127 writePin(F1, c & 0b00010);
128 writePin(F0, c & 0b00001);
129 } else {
130 writePinHigh(B5);
131 }
132}
133
134/* Row pin configuration
135 * row: 0 1 2 3 4 5
136 * pin: D0 D1 D2 D3 D5 B7
137 *
138 * Caps lock uses its own pin E2
139 */
140static void init_pins(void) {
141 unselect_cols();
142 for (uint8_t x = 0; x < MATRIX_ROWS; x++) {
143 setPinInput(row_pins[x]);
144 }
145
146 setPinInputHigh(E2);
147}
148
149static bool read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col) {
131 bool matrix_changed = false; 150 bool matrix_changed = false;
132 151
133 // Select col and wait for col selecton to stabilize 152 // Select col and wait for col selecton to stabilize
@@ -135,42 +154,32 @@ static bool read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col)
135 wait_us(30); 154 wait_us(30);
136 155
137 // For each row... 156 // For each row...
138 for(uint8_t row_index = 0; row_index < MATRIX_ROWS; row_index++) 157 for (uint8_t row_index = 0; row_index < MATRIX_ROWS; row_index++) {
139 {
140 // Store last value of row prior to reading 158 // Store last value of row prior to reading
141 matrix_row_t last_row_value = current_matrix[row_index]; 159 matrix_row_t last_row_value = current_matrix[row_index];
142 160
143 // Check row pin state 161 // Check row pin state
144 // Use the otherwise unused row: 3, col: 0 for caps lock 162 // Use the otherwise unused row: 3, col: 0 for caps lock
145 if (row_index == 3 && current_col == 0) { 163 if (row_index == 3 && current_col == 0) {
146 // Pin E2 uses active low 164 if (readPin(E2) == 0) {
147 if ((_SFR_IO8(E2 >> 4) & _BV(E2 & 0xF)) == 0)
148 {
149 // Pin LO, set col bit 165 // Pin LO, set col bit
150 current_matrix[row_index] |= (COL_SHIFTER << current_col); 166 current_matrix[row_index] |= (ROW_SHIFTER << current_col);
151 } 167 } else {
152 else
153 {
154 // Pin HI, clear col bit 168 // Pin HI, clear col bit
155 current_matrix[row_index] &= ~(COL_SHIFTER << current_col); 169 current_matrix[row_index] &= ~(ROW_SHIFTER << current_col);
156 } 170 }
157 } 171 } else {
158 else { 172 if (readPin(row_pins[row_index]) == 0) {
159 if ((_SFR_IO8(row_pins[row_index] >> 4) & _BV(row_pins[row_index] & 0xF))) 173 // Pin HI, clear col bit
160 { 174 current_matrix[row_index] &= ~(ROW_SHIFTER << current_col);
161 // Pin HI, set col bit 175 } else {
162 current_matrix[row_index] |= (COL_SHIFTER << current_col); 176 // Pin LO, set col bit
163 } 177 current_matrix[row_index] |= (ROW_SHIFTER << current_col);
164 else
165 {
166 // Pin LO, clear col bit
167 current_matrix[row_index] &= ~(COL_SHIFTER << current_col);
168 } 178 }
169 } 179 }
170 180
171 // Determine if the matrix changed state 181 // Determine if the matrix changed state
172 if ((last_row_value != current_matrix[row_index]) && !(matrix_changed)) 182 if ((last_row_value != current_matrix[row_index]) && !(matrix_changed)) {
173 {
174 matrix_changed = true; 183 matrix_changed = true;
175 } 184 }
176 } 185 }
@@ -181,131 +190,31 @@ static bool read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col)
181 return matrix_changed; 190 return matrix_changed;
182} 191}
183 192
184/* Row pin configuration 193void matrix_init(void) {
185 * row: 0 1 2 3 4 5 194 // initialize key pins
186 * pin: D0 D1 D2 D3 D5 B7 195 init_pins();
187 *
188 * Caps lock uses its own pin E2
189 */
190static void init_rows(void)
191{
192 DDRD &= ~((1<<0)| (1<<1) | (1<<2) | (1<<3) | (1<<5)); // IN
193 PORTD &= ~((1<<0)| (1<<1) | (1<<2) | (1<<3) | (1<<5)); // LO
194 DDRB &= ~(1<<7); // IN
195 PORTB &= ~(1<<7); // LO
196
197 DDRE &= ~(1<<2); // IN
198 PORTE |= (1<<2); // HI
199}
200 196
201/* Columns 0 - 15 197 // initialize matrix state: all keys off
202 * These columns uses two 74HC237D 3 to 8 bit demultiplexers. 198 for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
203 * col / pin: PC6 PB6 PF0 PF1 PC7 199 raw_matrix[i] = 0;
204 * 0: 1 0 0 0 0 200 matrix[i] = 0;
205 * 1: 1 0 1 0 0 201 }
206 * 2: 1 0 0 1 0
207 * 3: 1 0 1 1 0
208 * 4: 1 0 0 0 1
209 * 5: 1 0 1 0 1
210 * 6: 1 0 0 1 1
211 * 7: 1 0 1 1 1
212 * 8: 0 1 0 0 0
213 * 9: 0 1 1 0 0
214 * 10: 0 1 0 1 0
215 * 11: 0 1 1 1 0
216 * 12: 0 1 0 0 1
217 * 13: 0 1 1 0 1
218 * 14: 0 1 0 1 1
219 * 15: 0 1 1 1 1
220 *
221 * col: 16
222 * pin: PB5
223 */
224static void unselect_cols(void)
225{
226 DDRB |= (1<<5) | (1<<6); // OUT
227 PORTB &= ~((1<<5) | (1<<6)); // LO
228 202
229 DDRC |= (1<<6) | (1<<7); // OUT 203 debounce_init(MATRIX_ROWS);
230 PORTC &= ~((1<<6) | (1<<7)); // LO
231 204
232 DDRF |= (1<<0) | (1<<1); // OUT 205 matrix_init_quantum();
233 PORTF &= ~((1<<0) | (1<<1)); // LO
234} 206}
235 207
236static void select_col(uint8_t col) 208uint8_t matrix_scan(void) {
237{ 209 bool changed = false;
238 switch (col) { 210
239 case 0: 211 for (uint8_t current_col = 0; current_col < MATRIX_COLS; current_col++) {
240 PORTC |= (1<<6); // HI 212 changed |= read_rows_on_col(raw_matrix, current_col);
241 break;
242 case 1:
243 PORTC |= (1<<6); // HI
244 PORTF |= (1<<0); // HI
245 break;
246 case 2:
247 PORTC |= (1<<6); // HI
248 PORTF |= (1<<1); // HI
249 break;
250 case 3:
251 PORTC |= (1<<6); // HI
252 PORTF |= (1<<0) | (1<<1); // HI
253 break;
254 case 4:
255 PORTC |= (1<<6); // HI
256 PORTC |= (1<<7); // HI
257 break;
258 case 5:
259 PORTC |= (1<<6); // HI
260 PORTF |= (1<<0); // HI
261 PORTC |= (1<<7); // HI
262 break;
263 case 6:
264 PORTC |= (1<<6); // HI
265 PORTF |= (1<<1); // HI
266 PORTC |= (1<<7); // HI
267 break;
268 case 7:
269 PORTC |= (1<<6); // HI
270 PORTF |= (1<<0) | (1<<1); // HI
271 PORTC |= (1<<7); // HI
272 break;
273 case 8:
274 PORTB |= (1<<6); // HI
275 break;
276 case 9:
277 PORTB |= (1<<6); // HI
278 PORTF |= (1<<0); // HI
279 break;
280 case 10:
281 PORTB |= (1<<6); // HI
282 PORTF |= (1<<1); // HI
283 break;
284 case 11:
285 PORTB |= (1<<6); // HI
286 PORTF |= (1<<0) | (1<<1); // HI
287 break;
288 case 12:
289 PORTB |= (1<<6); // HI
290 PORTC |= (1<<7); // HI
291 break;
292 case 13:
293 PORTB |= (1<<6); // HI
294 PORTF |= (1<<0); // HI
295 PORTC |= (1<<7); // HI
296 break;
297 case 14:
298 PORTB |= (1<<6); // HI
299 PORTF |= (1<<1); // HI
300 PORTC |= (1<<7); // HI
301 break;
302 case 15:
303 PORTB |= (1<<6); // HI
304 PORTF |= (1<<0) | (1<<1); // HI
305 PORTC |= (1<<7); // HI
306 break;
307 case 16:
308 PORTB |= (1<<5); // HI
309 break;
310 } 213 }
214
215 debounce(raw_matrix, matrix, MATRIX_ROWS, changed);
216
217 matrix_scan_quantum();
218
219 return (uint8_t)changed;
311} 220}