aboutsummaryrefslogtreecommitdiff
path: root/keyboards/gergo/matrix.c
diff options
context:
space:
mode:
Diffstat (limited to 'keyboards/gergo/matrix.c')
-rw-r--r--keyboards/gergo/matrix.c239
1 files changed, 102 insertions, 137 deletions
diff --git a/keyboards/gergo/matrix.c b/keyboards/gergo/matrix.c
index 9886ecf15..aa1dc4842 100644
--- a/keyboards/gergo/matrix.c
+++ b/keyboards/gergo/matrix.c
@@ -29,10 +29,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
29#include "print.h" 29#include "print.h"
30#include "debug.h" 30#include "debug.h"
31#include "util.h" 31#include "util.h"
32#include "debounce.h"
32#include "pointing_device.h" 33#include "pointing_device.h"
33#include QMK_KEYBOARD_H 34#include QMK_KEYBOARD_H
34#ifdef DEBUG_MATRIX_SCAN_RATE 35#ifdef DEBUG_MATRIX_SCAN_RATE
35#include "timer.h" 36# include "timer.h"
36#endif 37#endif
37 38
38#ifdef BALLER 39#ifdef BALLER
@@ -117,12 +118,11 @@ static matrix_row_t raw_matrix[MATRIX_ROWS];
117// Debouncing: store for each key the number of scans until it's eligible to 118// Debouncing: store for each key the number of scans until it's eligible to
118// change. When scanning the matrix, ignore any changes in keys that have 119// change. When scanning the matrix, ignore any changes in keys that have
119// already changed in the last DEBOUNCE scans. 120// already changed in the last DEBOUNCE scans.
120static uint8_t debounce_matrix[MATRIX_ROWS * MATRIX_COLS];
121 121
122static matrix_row_t read_cols(uint8_t row); 122static matrix_row_t read_cols(uint8_t row);
123static void init_cols(void); 123static void init_cols(void);
124static void unselect_rows(void); 124static void unselect_rows(void);
125static void select_row(uint8_t row); 125static void select_row(uint8_t row);
126static void enableInterrupts(void); 126static void enableInterrupts(void);
127 127
128static uint8_t mcp23018_reset_loop; 128static uint8_t mcp23018_reset_loop;
@@ -134,11 +134,9 @@ uint32_t matrix_scan_count;
134#endif 134#endif
135 135
136 136
137__attribute__ ((weak)) 137__attribute__ ((weak)) void matrix_init_user(void) {}
138void matrix_init_user(void) {}
139 138
140__attribute__ ((weak)) 139__attribute__ ((weak)) void matrix_scan_user(void) {}
141void matrix_scan_user(void) {}
142 140
143__attribute__ ((weak)) 141__attribute__ ((weak))
144void matrix_init_kb(void) { 142void matrix_init_kb(void) {
@@ -150,39 +148,28 @@ void matrix_scan_kb(void) {
150 matrix_scan_user(); 148 matrix_scan_user();
151} 149}
152 150
153inline 151inline uint8_t matrix_rows(void) { return MATRIX_ROWS; }
154uint8_t matrix_rows(void)
155{
156 return MATRIX_ROWS;
157}
158 152
159inline 153inline uint8_t matrix_cols(void) { return MATRIX_COLS; }
160uint8_t matrix_cols(void)
161{
162 return MATRIX_COLS;
163}
164 154
165 155
166void matrix_init(void) 156void matrix_init(void) {
167{
168 // initialize row and col 157 // initialize row and col
169 mcp23018_status = init_mcp23018(); 158 mcp23018_status = init_mcp23018();
170 unselect_rows(); 159 unselect_rows();
171 init_cols(); 160 init_cols();
172 161
173 // initialize matrix state: all keys off 162 // initialize matrix state: all keys off
174 for (uint8_t i=0; i < MATRIX_ROWS; i++) { 163 for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
175 matrix[i] = 0; 164 matrix[i] = 0;
176 raw_matrix[i] = 0; 165 raw_matrix[i] = 0;
177 for (uint8_t j=0; j < MATRIX_COLS; ++j) { 166 }
178 debounce_matrix[i * MATRIX_COLS + j] = 0;
179 }
180 }
181 167
182#ifdef DEBUG_MATRIX_SCAN_RATE 168#ifdef DEBUG_MATRIX_SCAN_RATE
183 matrix_timer = timer_read32(); 169 matrix_timer = timer_read32();
184 matrix_scan_count = 0; 170 matrix_scan_count = 0;
185#endif 171#endif
172 debounce_init(MATRIX_ROWS);
186 matrix_init_quantum(); 173 matrix_init_quantum();
187} 174}
188 175
@@ -198,130 +185,120 @@ void matrix_power_up(void) {
198 } 185 }
199 186
200#ifdef DEBUG_MATRIX_SCAN_RATE 187#ifdef DEBUG_MATRIX_SCAN_RATE
201 matrix_timer = timer_read32(); 188 matrix_timer = timer_read32();
202 matrix_scan_count = 0; 189 matrix_scan_count = 0;
203#endif 190#endif
204 191
205} 192}
206 193
207// Returns a matrix_row_t whose bits are set if the corresponding key should be 194// Reads and stores a row, returning
208// eligible to change in this scan. 195// whether a change occurred.
209matrix_row_t debounce_mask(matrix_row_t rawcols, uint8_t row) { 196static inline bool store_raw_matrix_row(uint8_t index) {
210 matrix_row_t result = 0; 197 matrix_row_t temp = read_cols(index);
211 matrix_row_t change = rawcols ^ raw_matrix[row]; 198 if (raw_matrix[index] != temp) {
212 raw_matrix[row] = rawcols; 199 raw_matrix[index] = temp;
213 for (uint8_t i = 0; i < MATRIX_COLS; ++i) { 200 return true;
214 if (debounce_matrix[row * MATRIX_COLS + i]) {
215 --debounce_matrix[row * MATRIX_COLS + i];
216 } else {
217 result |= (1 << i);
218 }
219 if (change & (1 << i)) {
220 debounce_matrix[row * MATRIX_COLS + i] = DEBOUNCE;
221 }
222 } 201 }
223 return result; 202 return false;
224} 203}
225 204
226matrix_row_t debounce_read_cols(uint8_t row) {
227 // Read the row without debouncing filtering and store it for later usage.
228 matrix_row_t cols = read_cols(row);
229 // Get the Debounce mask.
230 matrix_row_t mask = debounce_mask(cols, row);
231 // debounce the row and return the result.
232 return (cols & mask) | (matrix[row] & ~mask);;
233}
234 205
235uint8_t matrix_scan(void)
236{
237 // TODO: Find what is trashing interrupts
238 enableInterrupts();
239 206
240 // First we handle the mouse inputs 207uint8_t matrix_scan(void) {
241 #ifdef BALLER 208 // TODO: Find what is trashing interrupts
242 uint8_t pBtn = PINE & TRKBTN; 209 enableInterrupts();
210
211 // First we handle the mouse inputs
212#ifdef BALLER
213 uint8_t pBtn = PINE & TRKBTN;
243 214
244 #ifdef DEBUG_BALLER 215 #ifdef DEBUG_BALLER
245 // Compare to previous, mod report 216 // Compare to previous, mod report
246 if (tbUpCnt + tbDnCnt + tbLtCnt + tbRtCnt != 0) 217 if (tbUpCnt + tbDnCnt + tbLtCnt + tbRtCnt != 0)
247 xprintf("U: %d D: %d L: %d R: %d B: %d\n", tbUpCnt, tbDnCnt, tbLtCnt, tbRtCnt, (trkBtnState >> 6)); 218 xprintf("U: %d D: %d L: %d R: %d B: %d\n", tbUpCnt, tbDnCnt, tbLtCnt, tbRtCnt, (trkBtnState >> 6));
248 #endif 219 #endif
249 220
250 // Modify the report 221 // Modify the report
251 report_mouse_t pRprt = pointing_device_get_report(); 222 report_mouse_t pRprt = pointing_device_get_report();
252 223
253 // Scroll by default, move on layer 224 // Scroll by default, move on layer
254 if (layer_state == 0) { 225 if (layer_state == 0) {
255 pRprt.h += tbLtCnt * SCROLLSTEP; tbLtCnt = 0; 226 pRprt.h += tbLtCnt * SCROLLSTEP; tbLtCnt = 0;
256 pRprt.h -= tbRtCnt * SCROLLSTEP; tbRtCnt = 0; 227 pRprt.h -= tbRtCnt * SCROLLSTEP; tbRtCnt = 0;
257 pRprt.v -= tbUpCnt * SCROLLSTEP; tbUpCnt = 0; 228 pRprt.v -= tbUpCnt * SCROLLSTEP; tbUpCnt = 0;
258 pRprt.v += tbDnCnt * SCROLLSTEP; tbDnCnt = 0; 229 pRprt.v += tbDnCnt * SCROLLSTEP; tbDnCnt = 0;
259 } else { 230 } else {
260 pRprt.x -= tbLtCnt * TRKSTEP * (layer_state - 1); tbLtCnt = 0; 231 pRprt.x -= tbLtCnt * TRKSTEP * (layer_state - 1); tbLtCnt = 0;
261 pRprt.x += tbRtCnt * TRKSTEP * (layer_state - 1); tbRtCnt = 0; 232 pRprt.x += tbRtCnt * TRKSTEP * (layer_state - 1); tbRtCnt = 0;
262 pRprt.y -= tbUpCnt * TRKSTEP * (layer_state - 1); tbUpCnt = 0; 233 pRprt.y -= tbUpCnt * TRKSTEP * (layer_state - 1); tbUpCnt = 0;
263 pRprt.y += tbDnCnt * TRKSTEP * (layer_state - 1); tbDnCnt = 0; 234 pRprt.y += tbDnCnt * TRKSTEP * (layer_state - 1); tbDnCnt = 0;
264 } 235 }
265 236
266 #ifdef DEBUG_BALLER 237#ifdef DEBUG_BALLER
267 if (pRprt.x != 0 || pRprt.y != 0) 238 if (pRprt.x != 0 || pRprt.y != 0)
268 xprintf("X: %d Y: %d\n", pRprt.x, pRprt.y); 239 xprintf("X: %d Y: %d\n", pRprt.x, pRprt.y);
269 #endif 240#endif
270 241
271 if ((pBtn != trkBtnState) && ((pBtn >> 6) == 0)) pRprt.buttons |= MOUSE_BTN1; 242 if ((pBtn != trkBtnState) && ((pBtn >> 6) == 0)) pRprt.buttons |= MOUSE_BTN1;
272 if ((pBtn != trkBtnState) && ((pBtn >> 6) == 1)) pRprt.buttons &= ~MOUSE_BTN1; 243 if ((pBtn != trkBtnState) && ((pBtn >> 6) == 1)) pRprt.buttons &= ~MOUSE_BTN1;
273 244
274 // Save state, push update 245 // Save state, push update
275 if (pRprt.x != 0 || pRprt.y != 0 || pRprt.h != 0 || pRprt.v != 0 || (trkBtnState != pBtn)) 246 if (pRprt.x != 0 || pRprt.y != 0 || pRprt.h != 0 || pRprt.v != 0 || (trkBtnState != pBtn))
276 pointing_device_set_report(pRprt); 247 pointing_device_set_report(pRprt);
277 248
278 trkBtnState = pBtn; 249 trkBtnState = pBtn;
279 #endif 250#endif
280 251
281 // Then the keyboard 252 // Then the keyboard
282 if (mcp23018_status) { // if there was an error 253 if (mcp23018_status) { // if there was an error
283 if (++mcp23018_reset_loop == 0) { 254 if (++mcp23018_reset_loop == 0) {
284 // if (++mcp23018_reset_loop >= 1300) { 255 // if (++mcp23018_reset_loop >= 1300) {
285 // since mcp23018_reset_loop is 8 bit - we'll try to reset once in 255 matrix scans 256 // since mcp23018_reset_loop is 8 bit - we'll try to reset once in 255 matrix scans
286 // this will be approx bit more frequent than once per second 257 // this will be approx bit more frequent than once per second
287 print("trying to reset mcp23018\n"); 258 print("trying to reset mcp23018\n");
288 mcp23018_status = init_mcp23018(); 259 mcp23018_status = init_mcp23018();
289 if (mcp23018_status) { 260 if (mcp23018_status) {
290 print("left side not responding\n"); 261 print("left side not responding\n");
291 } else { 262 } else {
292 print("left side attached\n"); 263 print("left side attached\n");
293 } 264 }
294 } 265 }
295 } 266 }
296 267
297#ifdef DEBUG_MATRIX_SCAN_RATE 268#ifdef DEBUG_MATRIX_SCAN_RATE
298 matrix_scan_count++; 269 matrix_scan_count++;
270
299 uint32_t timer_now = timer_read32(); 271 uint32_t timer_now = timer_read32();
300 if (TIMER_DIFF_32(timer_now, matrix_timer)>1000) { 272 if (TIMER_DIFF_32(timer_now, matrix_timer) > 1000) {
301 print("matrix scan frequency: "); 273 print("matrix scan frequency: ");
302 pdec(matrix_scan_count); 274 pdec(matrix_scan_count);
303 print("\n"); 275 print("\n");
304 276
305 matrix_timer = timer_now; 277 matrix_timer = timer_now;
306 matrix_scan_count = 0; 278 matrix_scan_count = 0;
307 } 279 }
308#endif 280#endif
281
282 bool changed = false;
309 for (uint8_t i = 0; i < MATRIX_ROWS_PER_SIDE; i++) { 283 for (uint8_t i = 0; i < MATRIX_ROWS_PER_SIDE; i++) {
310 select_row(i); 284 // select rows from left and right hands
311 // and select on left hand 285 uint8_t left_index = i;
312 select_row(i + MATRIX_ROWS_PER_SIDE); 286 uint8_t right_index = i + MATRIX_ROWS_PER_SIDE;
287 select_row(left_index);
288 select_row(right_index);
289
313 // we don't need a 30us delay anymore, because selecting a 290 // we don't need a 30us delay anymore, because selecting a
314 // left-hand row requires more than 30us for i2c. 291 // left-hand row requires more than 30us for i2c.
315 292
316 // grab cols from left hand 293 changed |= store_raw_matrix_row(left_index);
317 matrix[i] = debounce_read_cols(i); 294 changed |= store_raw_matrix_row(right_index);
318 // grab cols from right hand
319 matrix[i + MATRIX_ROWS_PER_SIDE] = debounce_read_cols(i + MATRIX_ROWS_PER_SIDE);
320 295
321 unselect_rows(); 296 unselect_rows();
322 } 297 }
323 298
299 debounce(raw_matrix, matrix, MATRIX_ROWS, changed);
324 matrix_scan_quantum(); 300 matrix_scan_quantum();
301
325 enableInterrupts(); 302 enableInterrupts();
326 303
327#ifdef DEBUG_MATRIX 304#ifdef DEBUG_MATRIX
@@ -338,20 +315,11 @@ bool matrix_is_modified(void) // deprecated and evidently not called.
338 return true; 315 return true;
339} 316}
340 317
341inline 318inline bool matrix_is_on(uint8_t row, uint8_t col) { return (matrix[row] & ((matrix_row_t)1 << col)); }
342bool matrix_is_on(uint8_t row, uint8_t col)
343{
344 return (matrix[row] & ((matrix_row_t)1<<col));
345}
346 319
347inline 320inline matrix_row_t matrix_get_row(uint8_t row) { return matrix[row]; }
348matrix_row_t matrix_get_row(uint8_t row)
349{
350 return matrix[row];
351}
352 321
353void matrix_print(void) 322void matrix_print(void) {
354{
355 print("\nr/c 0123456789ABCDEF\n"); 323 print("\nr/c 0123456789ABCDEF\n");
356 for (uint8_t row = 0; row < MATRIX_ROWS; row++) { 324 for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
357 phex(row); print(": "); 325 phex(row); print(": ");
@@ -360,8 +328,7 @@ void matrix_print(void)
360 } 328 }
361} 329}
362 330
363uint8_t matrix_key_count(void) 331uint8_t matrix_key_count(void) {
364{
365 uint8_t count = 0; 332 uint8_t count = 0;
366 for (uint8_t i = 0; i < MATRIX_ROWS; i++) { 333 for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
367 count += bitpop16(matrix[i]); 334 count += bitpop16(matrix[i]);
@@ -370,8 +337,7 @@ uint8_t matrix_key_count(void)
370} 337}
371 338
372// Remember this means ROWS 339// Remember this means ROWS
373static void init_cols(void) 340static void init_cols(void) {
374{
375 // init on mcp23018 341 // init on mcp23018
376 // not needed, already done as part of init_mcp23018() 342 // not needed, already done as part of init_mcp23018()
377 343
@@ -380,17 +346,16 @@ static void init_cols(void)
380 PORTF |= FMASK; 346 PORTF |= FMASK;
381} 347}
382 348
383static matrix_row_t read_cols(uint8_t row) 349static matrix_row_t read_cols(uint8_t row) {
384{
385 if (row < 7) { 350 if (row < 7) {
386 if (mcp23018_status) { // if there was an error 351 if (mcp23018_status) { // if there was an error
387 return 0; 352 return 0;
388 } else { 353 } else {
389 uint8_t data = 0; 354 uint8_t data = 0;
390 mcp23018_status = i2c_start(I2C_ADDR_WRITE, ERGODOX_EZ_I2C_TIMEOUT); if (mcp23018_status) goto out; 355 mcp23018_status = i2c_start(I2C_ADDR_WRITE, I2C_TIMEOUT); if (mcp23018_status) goto out;
391 mcp23018_status = i2c_write(GPIOB, ERGODOX_EZ_I2C_TIMEOUT); if (mcp23018_status) goto out; 356 mcp23018_status = i2c_write(GPIOB, I2C_TIMEOUT); if (mcp23018_status) goto out;
392 mcp23018_status = i2c_start(I2C_ADDR_READ, ERGODOX_EZ_I2C_TIMEOUT); if (mcp23018_status) goto out; 357 mcp23018_status = i2c_start(I2C_ADDR_READ, I2C_TIMEOUT); if (mcp23018_status) goto out;
393 mcp23018_status = i2c_read_nack(ERGODOX_EZ_I2C_TIMEOUT); if (mcp23018_status < 0) goto out; 358 mcp23018_status = i2c_read_nack(I2C_TIMEOUT); if (mcp23018_status < 0) goto out;
394 data = ~((uint8_t)mcp23018_status); 359 data = ~((uint8_t)mcp23018_status);
395 mcp23018_status = I2C_STATUS_SUCCESS; 360 mcp23018_status = I2C_STATUS_SUCCESS;
396 out: 361 out:
@@ -440,9 +405,9 @@ static void select_row(uint8_t row)
440 // select on mcp23018 405 // select on mcp23018
441 if (mcp23018_status) { // do nothing on error 406 if (mcp23018_status) { // do nothing on error
442 } else { // set active row low : 0 // set other rows hi-Z : 1 407 } else { // set active row low : 0 // set other rows hi-Z : 1
443 mcp23018_status = i2c_start(I2C_ADDR_WRITE, ERGODOX_EZ_I2C_TIMEOUT); if (mcp23018_status) goto out; 408 mcp23018_status = i2c_start(I2C_ADDR_WRITE, I2C_TIMEOUT); if (mcp23018_status) goto out;
444 mcp23018_status = i2c_write(GPIOA, ERGODOX_EZ_I2C_TIMEOUT); if (mcp23018_status) goto out; 409 mcp23018_status = i2c_write(GPIOA, I2C_TIMEOUT); if (mcp23018_status) goto out;
445 mcp23018_status = i2c_write(0xFF & ~(1<<row), ERGODOX_EZ_I2C_TIMEOUT); if (mcp23018_status) goto out; 410 mcp23018_status = i2c_write(0xFF & ~(1<<row), I2C_TIMEOUT); if (mcp23018_status) goto out;
446 out: 411 out:
447 i2c_stop(); 412 i2c_stop();
448 } 413 }