aboutsummaryrefslogtreecommitdiff
path: root/keyboards/mint60/matrix.c
diff options
context:
space:
mode:
authoreucalyn <hi.eucalyn@gmail.com>2018-08-20 05:26:42 +0900
committerDrashna Jaelre <drashna@live.com>2018-08-19 13:26:42 -0700
commit99da48c72b90e11e5ef945263530c6f8746848fd (patch)
tree9b70da4e151b00283553651c10cd2ae01067d967 /keyboards/mint60/matrix.c
parent4cc1edbb67beecd0081fb84d3b5365e55d1a41e1 (diff)
downloadqmk_firmware-99da48c72b90e11e5ef945263530c6f8746848fd.tar.gz
qmk_firmware-99da48c72b90e11e5ef945263530c6f8746848fd.zip
Keyboard: add mint60 keyboard (#3543)
* add mint60 * change source by reviews
Diffstat (limited to 'keyboards/mint60/matrix.c')
-rw-r--r--keyboards/mint60/matrix.c349
1 files changed, 349 insertions, 0 deletions
diff --git a/keyboards/mint60/matrix.c b/keyboards/mint60/matrix.c
new file mode 100644
index 000000000..6d8878332
--- /dev/null
+++ b/keyboards/mint60/matrix.c
@@ -0,0 +1,349 @@
1/*
2Copyright 2012 Jun Wako <wakojun@gmail.com>
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/*
19 * scan matrix
20 */
21#include <stdint.h>
22#include <stdbool.h>
23#include <avr/io.h>
24#include <avr/wdt.h>
25#include <avr/interrupt.h>
26#include <util/delay.h>
27#include "print.h"
28#include "debug.h"
29#include "util.h"
30#include "matrix.h"
31#include "split_util.h"
32#include "pro_micro.h"
33
34#ifdef USE_I2C
35# include "i2c.h"
36#else // USE_SERIAL
37# include "serial.h"
38#endif
39
40#ifndef DEBOUNCE
41# define DEBOUNCE 5
42#endif
43
44#define ERROR_DISCONNECT_COUNT 5
45
46static uint8_t debouncing = DEBOUNCE;
47static const int ROWS_PER_HAND = MATRIX_ROWS/2;
48static uint8_t error_count = 0;
49uint8_t is_master = 0 ;
50
51static const uint8_t row_pins[MATRIX_ROWS] = MATRIX_ROW_PINS;
52static const uint8_t col_pins[MATRIX_COLS] = MATRIX_COL_PINS;
53
54/* matrix state(1:on, 0:off) */
55static matrix_row_t matrix[MATRIX_ROWS];
56static matrix_row_t matrix_debouncing[MATRIX_ROWS];
57
58static matrix_row_t read_cols(void);
59static void init_cols(void);
60static void unselect_rows(void);
61static void select_row(uint8_t row);
62static uint8_t matrix_master_scan(void);
63
64
65__attribute__ ((weak))
66void matrix_init_kb(void) {
67 matrix_init_user();
68}
69
70__attribute__ ((weak))
71void matrix_scan_kb(void) {
72 matrix_scan_user();
73}
74
75__attribute__ ((weak))
76void matrix_init_user(void) {
77}
78
79__attribute__ ((weak))
80void matrix_scan_user(void) {
81}
82
83inline
84uint8_t matrix_rows(void)
85{
86 return MATRIX_ROWS;
87}
88
89inline
90uint8_t matrix_cols(void)
91{
92 return MATRIX_COLS;
93}
94
95void matrix_init(void)
96{
97 debug_enable = true;
98 debug_matrix = true;
99 debug_mouse = true;
100 // initialize row and col
101 unselect_rows();
102 init_cols();
103
104 TX_RX_LED_INIT;
105
106 // initialize matrix state: all keys off
107 for (uint8_t i=0; i < MATRIX_ROWS; i++) {
108 matrix[i] = 0;
109 matrix_debouncing[i] = 0;
110 }
111
112 is_master = has_usb();
113
114 matrix_init_quantum();
115}
116
117uint8_t _matrix_scan(void)
118{
119 // Right hand is stored after the left in the matirx so, we need to offset it
120 int offset = isLeftHand ? 0 : (ROWS_PER_HAND);
121
122 for (uint8_t i = 0; i < ROWS_PER_HAND; i++) {
123 select_row(i);
124 _delay_us(30); // without this wait read unstable value.
125 matrix_row_t cols = read_cols();
126 if (matrix_debouncing[i+offset] != cols) {
127 matrix_debouncing[i+offset] = cols;
128 debouncing = DEBOUNCE;
129 }
130 unselect_rows();
131 }
132
133 if (debouncing) {
134 if (--debouncing) {
135 _delay_ms(1);
136 } else {
137 for (uint8_t i = 0; i < ROWS_PER_HAND; i++) {
138 matrix[i+offset] = matrix_debouncing[i+offset];
139 }
140 }
141 }
142
143 return 1;
144}
145
146#ifdef USE_I2C
147
148// Get rows from other half over i2c
149int i2c_transaction(void) {
150 int slaveOffset = (isLeftHand) ? (ROWS_PER_HAND) : 0;
151
152 int err = i2c_master_start(SLAVE_I2C_ADDRESS + I2C_WRITE);
153 if (err) goto i2c_error;
154
155 // start of matrix stored at 0x00
156 err = i2c_master_write(0x00);
157 if (err) goto i2c_error;
158
159 // Start read
160 err = i2c_master_start(SLAVE_I2C_ADDRESS + I2C_READ);
161 if (err) goto i2c_error;
162
163 if (!err) {
164 int i;
165 for (i = 0; i < ROWS_PER_HAND-1; ++i) {
166 matrix[slaveOffset+i] = i2c_master_read(I2C_ACK);
167 }
168 matrix[slaveOffset+i] = i2c_master_read(I2C_NACK);
169 i2c_master_stop();
170 } else {
171i2c_error: // the cable is disconnceted, or something else went wrong
172 i2c_reset_state();
173 return err;
174 }
175
176 return 0;
177}
178
179#else // USE_SERIAL
180
181int serial_transaction(void) {
182 int slaveOffset = (isLeftHand) ? (ROWS_PER_HAND) : 0;
183 int ret=serial_update_buffers();
184 if (ret ) {
185 if(ret==2)RXLED1;
186 return 1;
187 }
188RXLED0;
189 for (int i = 0; i < ROWS_PER_HAND; ++i) {
190 matrix[slaveOffset+i] = serial_slave_buffer[i];
191 }
192 return 0;
193}
194#endif
195
196uint8_t matrix_scan(void)
197{
198 if (is_master) {
199 matrix_master_scan();
200 }else{
201 matrix_slave_scan();
202
203// if(serial_slave_DATA_CORRUPT()){
204// TXLED0;
205 int offset = (isLeftHand) ? ROWS_PER_HAND : 0;
206
207 for (int i = 0; i < ROWS_PER_HAND; ++i) {
208 matrix[offset+i] = serial_master_buffer[i];
209 }
210
211// }else{
212// TXLED1;
213// }
214
215 matrix_scan_quantum();
216 }
217 return 1;
218}
219
220
221uint8_t matrix_master_scan(void) {
222
223 int ret = _matrix_scan();
224
225#ifndef KEYBOARD_helix_rev1
226 int offset = (isLeftHand) ? 0 : ROWS_PER_HAND;
227
228#ifdef USE_I2C
229// for (int i = 0; i < ROWS_PER_HAND; ++i) {
230 /* i2c_slave_buffer[i] = matrix[offset+i]; */
231// i2c_slave_buffer[i] = matrix[offset+i];
232// }
233#else // USE_SERIAL
234 for (int i = 0; i < ROWS_PER_HAND; ++i) {
235 serial_master_buffer[i] = matrix[offset+i];
236 }
237#endif
238#endif
239
240#ifdef USE_I2C
241 if( i2c_transaction() ) {
242#else // USE_SERIAL
243 if( serial_transaction() ) {
244#endif
245 // turn on the indicator led when halves are disconnected
246 TXLED1;
247
248 error_count++;
249
250 if (error_count > ERROR_DISCONNECT_COUNT) {
251 // reset other half if disconnected
252 int slaveOffset = (isLeftHand) ? (ROWS_PER_HAND) : 0;
253 for (int i = 0; i < ROWS_PER_HAND; ++i) {
254 matrix[slaveOffset+i] = 0;
255 }
256 }
257 } else {
258 // turn off the indicator led on no error
259 TXLED0;
260 error_count = 0;
261 }
262 matrix_scan_quantum();
263 return ret;
264}
265
266void matrix_slave_scan(void) {
267 _matrix_scan();
268
269 int offset = (isLeftHand) ? 0 : ROWS_PER_HAND;
270
271#ifdef USE_I2C
272 for (int i = 0; i < ROWS_PER_HAND; ++i) {
273 /* i2c_slave_buffer[i] = matrix[offset+i]; */
274 i2c_slave_buffer[i] = matrix[offset+i];
275 }
276#else // USE_SERIAL
277 for (int i = 0; i < ROWS_PER_HAND; ++i) {
278 serial_slave_buffer[i] = matrix[offset+i];
279 }
280#endif
281}
282
283bool matrix_is_modified(void)
284{
285 if (debouncing) return false;
286 return true;
287}
288
289inline
290bool matrix_is_on(uint8_t row, uint8_t col)
291{
292 return (matrix[row] & ((matrix_row_t)1<<col));
293}
294
295inline
296matrix_row_t matrix_get_row(uint8_t row)
297{
298 return matrix[row];
299}
300
301void matrix_print(void)
302{
303 print("\nr/c 0123456789ABCDEF\n");
304 for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
305 phex(row); print(": ");
306 pbin_reverse16(matrix_get_row(row));
307 print("\n");
308 }
309}
310
311uint8_t matrix_key_count(void)
312{
313 uint8_t count = 0;
314 for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
315 count += bitpop16(matrix[i]);
316 }
317 return count;
318}
319
320static void init_cols(void)
321{
322 for(int x = 0; x < MATRIX_COLS; x++) {
323 _SFR_IO8((col_pins[x] >> 4) + 1) &= ~_BV(col_pins[x] & 0xF);
324 _SFR_IO8((col_pins[x] >> 4) + 2) |= _BV(col_pins[x] & 0xF);
325 }
326}
327
328static matrix_row_t read_cols(void)
329{
330 matrix_row_t result = 0;
331 for(int x = 0; x < MATRIX_COLS; x++) {
332 result |= (_SFR_IO8(col_pins[x] >> 4) & _BV(col_pins[x] & 0xF)) ? 0 : (1 << x);
333 }
334 return result;
335}
336
337static void unselect_rows(void)
338{
339 for(int x = 0; x < ROWS_PER_HAND; x++) {
340 _SFR_IO8((row_pins[x] >> 4) + 1) &= ~_BV(row_pins[x] & 0xF);
341 _SFR_IO8((row_pins[x] >> 4) + 2) |= _BV(row_pins[x] & 0xF);
342 }
343}
344
345static void select_row(uint8_t row)
346{
347 _SFR_IO8((row_pins[row] >> 4) + 1) |= _BV(row_pins[row] & 0xF);
348 _SFR_IO8((row_pins[row] >> 4) + 2) &= ~_BV(row_pins[row] & 0xF);
349}