aboutsummaryrefslogtreecommitdiff
path: root/keyboards/deltasplit75/matrix.c
diff options
context:
space:
mode:
Diffstat (limited to 'keyboards/deltasplit75/matrix.c')
-rw-r--r--keyboards/deltasplit75/matrix.c636
1 files changed, 318 insertions, 318 deletions
diff --git a/keyboards/deltasplit75/matrix.c b/keyboards/deltasplit75/matrix.c
index c3bb0b058..138969004 100644
--- a/keyboards/deltasplit75/matrix.c
+++ b/keyboards/deltasplit75/matrix.c
@@ -1,318 +1,318 @@
1/* 1/*
2Copyright 2012 Jun Wako <wakojun@gmail.com> 2Copyright 2012 Jun Wako <wakojun@gmail.com>
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
6the Free Software Foundation, either version 2 of the License, or 6the Free Software Foundation, either version 2 of the License, or
7(at your option) any later version. 7(at your option) any later version.
8 8
9This program is distributed in the hope that it will be useful, 9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of 10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details. 12GNU General Public License for more details.
13 13
14You should have received a copy of the GNU General Public License 14You should have received a copy of the GNU General Public License
15along with this program. If not, see <http://www.gnu.org/licenses/>. 15along with this program. If not, see <http://www.gnu.org/licenses/>.
16*/ 16*/
17 17
18/* 18/*
19 * scan matrix 19 * scan matrix
20 */ 20 */
21#include <stdint.h> 21#include <stdint.h>
22#include <stdbool.h> 22#include <stdbool.h>
23#include <avr/io.h> 23#include <avr/io.h>
24#include <avr/wdt.h> 24#include <avr/wdt.h>
25#include <avr/interrupt.h> 25#include <avr/interrupt.h>
26#include <util/delay.h> 26#include <util/delay.h>
27#include "print.h" 27#include "print.h"
28#include "debug.h" 28#include "debug.h"
29#include "util.h" 29#include "util.h"
30#include "matrix.h" 30#include "matrix.h"
31#include "split_util.h" 31#include "split_util.h"
32#include "pro_micro.h" 32#include "pro_micro.h"
33#include "config.h" 33#include "config.h"
34 34
35#ifdef USE_I2C 35#ifdef USE_I2C
36# include "i2c.h" 36# include "i2c.h"
37#else // USE_SERIAL 37#else // USE_SERIAL
38# include "serial.h" 38# include "serial.h"
39#endif 39#endif
40 40
41#ifndef DEBOUNCE 41#ifndef DEBOUNCE
42# define DEBOUNCE 5 42# define DEBOUNCE 5
43#endif 43#endif
44 44
45#define ERROR_DISCONNECT_COUNT 5 45#define ERROR_DISCONNECT_COUNT 5
46 46
47static uint8_t debouncing = DEBOUNCE; 47static uint8_t debouncing = DEBOUNCE;
48static const int ROWS_PER_HAND = MATRIX_ROWS/2; 48static const int ROWS_PER_HAND = MATRIX_ROWS/2;
49static uint8_t error_count = 0; 49static uint8_t error_count = 0;
50 50
51static const uint8_t row_pins[MATRIX_ROWS] = MATRIX_ROW_PINS; 51static const uint8_t row_pins[MATRIX_ROWS] = MATRIX_ROW_PINS;
52static const uint8_t col_pins[MATRIX_COLS] = MATRIX_COL_PINS; 52static const uint8_t col_pins[MATRIX_COLS] = MATRIX_COL_PINS;
53 53
54/* matrix state(1:on, 0:off) */ 54/* matrix state(1:on, 0:off) */
55static matrix_row_t matrix[MATRIX_ROWS]; 55static matrix_row_t matrix[MATRIX_ROWS];
56static matrix_row_t matrix_debouncing[MATRIX_ROWS]; 56static matrix_row_t matrix_debouncing[MATRIX_ROWS];
57 57
58static matrix_row_t read_cols(void); 58static matrix_row_t read_cols(void);
59static void init_cols(void); 59static void init_cols(void);
60static void unselect_rows(void); 60static void unselect_rows(void);
61static void select_row(uint8_t row); 61static void select_row(uint8_t row);
62 62
63__attribute__ ((weak)) 63__attribute__ ((weak))
64void matrix_init_quantum(void) { 64void matrix_init_quantum(void) {
65 matrix_init_kb(); 65 matrix_init_kb();
66} 66}
67 67
68__attribute__ ((weak)) 68__attribute__ ((weak))
69void matrix_scan_quantum(void) { 69void matrix_scan_quantum(void) {
70 matrix_scan_kb(); 70 matrix_scan_kb();
71} 71}
72 72
73__attribute__ ((weak)) 73__attribute__ ((weak))
74void matrix_init_kb(void) { 74void matrix_init_kb(void) {
75 matrix_init_user(); 75 matrix_init_user();
76} 76}
77 77
78__attribute__ ((weak)) 78__attribute__ ((weak))
79void matrix_scan_kb(void) { 79void matrix_scan_kb(void) {
80 matrix_scan_user(); 80 matrix_scan_user();
81} 81}
82 82
83__attribute__ ((weak)) 83__attribute__ ((weak))
84void matrix_init_user(void) { 84void matrix_init_user(void) {
85} 85}
86 86
87__attribute__ ((weak)) 87__attribute__ ((weak))
88void matrix_scan_user(void) { 88void matrix_scan_user(void) {
89} 89}
90 90
91inline 91inline
92uint8_t matrix_rows(void) 92uint8_t matrix_rows(void)
93{ 93{
94 return MATRIX_ROWS; 94 return MATRIX_ROWS;
95} 95}
96 96
97inline 97inline
98uint8_t matrix_cols(void) 98uint8_t matrix_cols(void)
99{ 99{
100 return MATRIX_COLS; 100 return MATRIX_COLS;
101} 101}
102 102
103void matrix_init(void) 103void matrix_init(void)
104{ 104{
105 debug_enable = true; 105 debug_enable = true;
106 debug_matrix = true; 106 debug_matrix = true;
107 debug_mouse = true; 107 debug_mouse = true;
108 // initialize row and col 108 // initialize row and col
109 unselect_rows(); 109 unselect_rows();
110 init_cols(); 110 init_cols();
111 111
112 TX_RX_LED_INIT; 112 TX_RX_LED_INIT;
113 113
114 // initialize matrix state: all keys off 114 // initialize matrix state: all keys off
115 for (uint8_t i=0; i < MATRIX_ROWS; i++) { 115 for (uint8_t i=0; i < MATRIX_ROWS; i++) {
116 matrix[i] = 0; 116 matrix[i] = 0;
117 matrix_debouncing[i] = 0; 117 matrix_debouncing[i] = 0;
118 } 118 }
119 119
120 matrix_init_quantum(); 120 matrix_init_quantum();
121} 121}
122 122
123uint8_t _matrix_scan(void) 123uint8_t _matrix_scan(void)
124{ 124{
125 // Right hand is stored after the left in the matirx so, we need to offset it 125 // Right hand is stored after the left in the matirx so, we need to offset it
126 int offset = isLeftHand ? 0 : (ROWS_PER_HAND); 126 int offset = isLeftHand ? 0 : (ROWS_PER_HAND);
127 127
128 for (uint8_t i = 0; i < ROWS_PER_HAND; i++) { 128 for (uint8_t i = 0; i < ROWS_PER_HAND; i++) {
129 select_row(i); 129 select_row(i);
130 _delay_us(30); // without this wait read unstable value. 130 _delay_us(30); // without this wait read unstable value.
131 matrix_row_t cols = read_cols(); 131 matrix_row_t cols = read_cols();
132 if (matrix_debouncing[i+offset] != cols) { 132 if (matrix_debouncing[i+offset] != cols) {
133 matrix_debouncing[i+offset] = cols; 133 matrix_debouncing[i+offset] = cols;
134 debouncing = DEBOUNCE; 134 debouncing = DEBOUNCE;
135 } 135 }
136 unselect_rows(); 136 unselect_rows();
137 } 137 }
138 138
139 if (debouncing) { 139 if (debouncing) {
140 if (--debouncing) { 140 if (--debouncing) {
141 _delay_ms(1); 141 _delay_ms(1);
142 } else { 142 } else {
143 for (uint8_t i = 0; i < ROWS_PER_HAND; i++) { 143 for (uint8_t i = 0; i < ROWS_PER_HAND; i++) {
144 matrix[i+offset] = matrix_debouncing[i+offset]; 144 matrix[i+offset] = matrix_debouncing[i+offset];
145 } 145 }
146 } 146 }
147 } 147 }
148 148
149 return 1; 149 return 1;
150} 150}
151 151
152#ifdef USE_I2C 152#ifdef USE_I2C
153 153
154// Get rows from other half over i2c 154// Get rows from other half over i2c
155int i2c_transaction(void) { 155int i2c_transaction(void) {
156 int slaveOffset = (isLeftHand) ? (ROWS_PER_HAND) : 0; 156 int slaveOffset = (isLeftHand) ? (ROWS_PER_HAND) : 0;
157 157
158 int err = i2c_master_start(SLAVE_I2C_ADDRESS + I2C_WRITE); 158 int err = i2c_master_start(SLAVE_I2C_ADDRESS + I2C_WRITE);
159 if (err) goto i2c_error; 159 if (err) goto i2c_error;
160 160
161 // start of matrix stored at 0x00 161 // start of matrix stored at 0x00
162 err = i2c_master_write(0x00); 162 err = i2c_master_write(0x00);
163 if (err) goto i2c_error; 163 if (err) goto i2c_error;
164 164
165 // Start read 165 // Start read
166 err = i2c_master_start(SLAVE_I2C_ADDRESS + I2C_READ); 166 err = i2c_master_start(SLAVE_I2C_ADDRESS + I2C_READ);
167 if (err) goto i2c_error; 167 if (err) goto i2c_error;
168 168
169 if (!err) { 169 if (!err) {
170 int i; 170 int i;
171 for (i = 0; i < ROWS_PER_HAND-1; ++i) { 171 for (i = 0; i < ROWS_PER_HAND-1; ++i) {
172 matrix[slaveOffset+i] = i2c_master_read(I2C_ACK); 172 matrix[slaveOffset+i] = i2c_master_read(I2C_ACK);
173 } 173 }
174 matrix[slaveOffset+i] = i2c_master_read(I2C_NACK); 174 matrix[slaveOffset+i] = i2c_master_read(I2C_NACK);
175 i2c_master_stop(); 175 i2c_master_stop();
176 } else { 176 } else {
177i2c_error: // the cable is disconnceted, or something else went wrong 177i2c_error: // the cable is disconnceted, or something else went wrong
178 i2c_reset_state(); 178 i2c_reset_state();
179 return err; 179 return err;
180 } 180 }
181 181
182 return 0; 182 return 0;
183} 183}
184 184
185#else // USE_SERIAL 185#else // USE_SERIAL
186 186
187int serial_transaction(void) { 187int serial_transaction(void) {
188 int slaveOffset = (isLeftHand) ? (ROWS_PER_HAND) : 0; 188 int slaveOffset = (isLeftHand) ? (ROWS_PER_HAND) : 0;
189 189
190 if (serial_update_buffers()) { 190 if (serial_update_buffers()) {
191 return 1; 191 return 1;
192 } 192 }
193 193
194 for (int i = 0; i < ROWS_PER_HAND; ++i) { 194 for (int i = 0; i < ROWS_PER_HAND; ++i) {
195 matrix[slaveOffset+i] = serial_slave_buffer[i]; 195 matrix[slaveOffset+i] = serial_slave_buffer[i];
196 } 196 }
197 return 0; 197 return 0;
198} 198}
199#endif 199#endif
200 200
201uint8_t matrix_scan(void) 201uint8_t matrix_scan(void)
202{ 202{
203 int ret = _matrix_scan(); 203 int ret = _matrix_scan();
204 204
205 205
206 206
207#ifdef USE_I2C 207#ifdef USE_I2C
208 if( i2c_transaction() ) { 208 if( i2c_transaction() ) {
209#else // USE_SERIAL 209#else // USE_SERIAL
210 if( serial_transaction() ) { 210 if( serial_transaction() ) {
211#endif 211#endif
212 // turn on the indicator led when halves are disconnected 212 // turn on the indicator led when halves are disconnected
213 TXLED1; 213 TXLED1;
214 214
215 error_count++; 215 error_count++;
216 216
217 if (error_count > ERROR_DISCONNECT_COUNT) { 217 if (error_count > ERROR_DISCONNECT_COUNT) {
218 // reset other half if disconnected 218 // reset other half if disconnected
219 int slaveOffset = (isLeftHand) ? (ROWS_PER_HAND) : 0; 219 int slaveOffset = (isLeftHand) ? (ROWS_PER_HAND) : 0;
220 for (int i = 0; i < ROWS_PER_HAND; ++i) { 220 for (int i = 0; i < ROWS_PER_HAND; ++i) {
221 matrix[slaveOffset+i] = 0; 221 matrix[slaveOffset+i] = 0;
222 } 222 }
223 } 223 }
224 } else { 224 } else {
225 // turn off the indicator led on no error 225 // turn off the indicator led on no error
226 TXLED0; 226 TXLED0;
227 error_count = 0; 227 error_count = 0;
228 } 228 }
229 229
230 matrix_scan_quantum(); 230 matrix_scan_quantum();
231 231
232 return ret; 232 return ret;
233} 233}
234 234
235void matrix_slave_scan(void) { 235void matrix_slave_scan(void) {
236 _matrix_scan(); 236 _matrix_scan();
237 237
238 int offset = (isLeftHand) ? 0 : (MATRIX_ROWS / 2); 238 int offset = (isLeftHand) ? 0 : (MATRIX_ROWS / 2);
239 239
240#ifdef USE_I2C 240#ifdef USE_I2C
241 for (int i = 0; i < ROWS_PER_HAND; ++i) { 241 for (int i = 0; i < ROWS_PER_HAND; ++i) {
242 /* i2c_slave_buffer[i] = matrix[offset+i]; */ 242 /* i2c_slave_buffer[i] = matrix[offset+i]; */
243 i2c_slave_buffer[i] = matrix[offset+i]; 243 i2c_slave_buffer[i] = matrix[offset+i];
244 } 244 }
245#else // USE_SERIAL 245#else // USE_SERIAL
246 for (int i = 0; i < ROWS_PER_HAND; ++i) { 246 for (int i = 0; i < ROWS_PER_HAND; ++i) {
247 serial_slave_buffer[i] = matrix[offset+i]; 247 serial_slave_buffer[i] = matrix[offset+i];
248 } 248 }
249#endif 249#endif
250} 250}
251 251
252bool matrix_is_modified(void) 252bool matrix_is_modified(void)
253{ 253{
254 if (debouncing) return false; 254 if (debouncing) return false;
255 return true; 255 return true;
256} 256}
257 257
258inline 258inline
259bool matrix_is_on(uint8_t row, uint8_t col) 259bool matrix_is_on(uint8_t row, uint8_t col)
260{ 260{
261 return (matrix[row] & ((matrix_row_t)1<<col)); 261 return (matrix[row] & ((matrix_row_t)1<<col));
262} 262}
263 263
264inline 264inline
265matrix_row_t matrix_get_row(uint8_t row) 265matrix_row_t matrix_get_row(uint8_t row)
266{ 266{
267 return matrix[row]; 267 return matrix[row];
268} 268}
269 269
270void matrix_print(void) 270void matrix_print(void)
271{ 271{
272 print("\nr/c 0123456789ABCDEF\n"); 272 print("\nr/c 0123456789ABCDEF\n");
273 for (uint8_t row = 0; row < MATRIX_ROWS; row++) { 273 for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
274 phex(row); print(": "); 274 phex(row); print(": ");
275 pbin_reverse16(matrix_get_row(row)); 275 pbin_reverse16(matrix_get_row(row));
276 print("\n"); 276 print("\n");
277 } 277 }
278} 278}
279 279
280uint8_t matrix_key_count(void) 280uint8_t matrix_key_count(void)
281{ 281{
282 uint8_t count = 0; 282 uint8_t count = 0;
283 for (uint8_t i = 0; i < MATRIX_ROWS; i++) { 283 for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
284 count += bitpop16(matrix[i]); 284 count += bitpop16(matrix[i]);
285 } 285 }
286 return count; 286 return count;
287} 287}
288 288
289static void init_cols(void) 289static void init_cols(void)
290{ 290{
291 for(int x = 0; x < MATRIX_COLS; x++) { 291 for(int x = 0; x < MATRIX_COLS; x++) {
292 _SFR_IO8((col_pins[x] >> 4) + 1) &= ~_BV(col_pins[x] & 0xF); 292 _SFR_IO8((col_pins[x] >> 4) + 1) &= ~_BV(col_pins[x] & 0xF);
293 _SFR_IO8((col_pins[x] >> 4) + 2) |= _BV(col_pins[x] & 0xF); 293 _SFR_IO8((col_pins[x] >> 4) + 2) |= _BV(col_pins[x] & 0xF);
294 } 294 }
295} 295}
296 296
297static matrix_row_t read_cols(void) 297static matrix_row_t read_cols(void)
298{ 298{
299 matrix_row_t result = 0; 299 matrix_row_t result = 0;
300 for(int x = 0; x < MATRIX_COLS; x++) { 300 for(int x = 0; x < MATRIX_COLS; x++) {
301 result |= (_SFR_IO8(col_pins[x] >> 4) & _BV(col_pins[x] & 0xF)) ? 0 : (1 << x); 301 result |= (_SFR_IO8(col_pins[x] >> 4) & _BV(col_pins[x] & 0xF)) ? 0 : (1 << x);
302 } 302 }
303 return result; 303 return result;
304} 304}
305 305
306static void unselect_rows(void) 306static void unselect_rows(void)
307{ 307{
308 for(int x = 0; x < ROWS_PER_HAND; x++) { 308 for(int x = 0; x < ROWS_PER_HAND; x++) {
309 _SFR_IO8((row_pins[x] >> 4) + 1) &= ~_BV(row_pins[x] & 0xF); 309 _SFR_IO8((row_pins[x] >> 4) + 1) &= ~_BV(row_pins[x] & 0xF);
310 _SFR_IO8((row_pins[x] >> 4) + 2) |= _BV(row_pins[x] & 0xF); 310 _SFR_IO8((row_pins[x] >> 4) + 2) |= _BV(row_pins[x] & 0xF);
311 } 311 }
312} 312}
313 313
314static void select_row(uint8_t row) 314static void select_row(uint8_t row)
315{ 315{
316 _SFR_IO8((row_pins[row] >> 4) + 1) |= _BV(row_pins[row] & 0xF); 316 _SFR_IO8((row_pins[row] >> 4) + 1) |= _BV(row_pins[row] & 0xF);
317 _SFR_IO8((row_pins[row] >> 4) + 2) &= ~_BV(row_pins[row] & 0xF); 317 _SFR_IO8((row_pins[row] >> 4) + 2) &= ~_BV(row_pins[row] & 0xF);
318} 318}