diff options
Diffstat (limited to 'keyboards/gergo/matrix.c')
| -rw-r--r-- | keyboards/gergo/matrix.c | 239 |
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. |
| 120 | static uint8_t debounce_matrix[MATRIX_ROWS * MATRIX_COLS]; | ||
| 121 | 121 | ||
| 122 | static matrix_row_t read_cols(uint8_t row); | 122 | static matrix_row_t read_cols(uint8_t row); |
| 123 | static void init_cols(void); | 123 | static void init_cols(void); |
| 124 | static void unselect_rows(void); | 124 | static void unselect_rows(void); |
| 125 | static void select_row(uint8_t row); | 125 | static void select_row(uint8_t row); |
| 126 | static void enableInterrupts(void); | 126 | static void enableInterrupts(void); |
| 127 | 127 | ||
| 128 | static uint8_t mcp23018_reset_loop; | 128 | static 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) {} |
| 138 | void matrix_init_user(void) {} | ||
| 139 | 138 | ||
| 140 | __attribute__ ((weak)) | 139 | __attribute__ ((weak)) void matrix_scan_user(void) {} |
| 141 | void matrix_scan_user(void) {} | ||
| 142 | 140 | ||
| 143 | __attribute__ ((weak)) | 141 | __attribute__ ((weak)) |
| 144 | void matrix_init_kb(void) { | 142 | void 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 | ||
| 153 | inline | 151 | inline uint8_t matrix_rows(void) { return MATRIX_ROWS; } |
| 154 | uint8_t matrix_rows(void) | ||
| 155 | { | ||
| 156 | return MATRIX_ROWS; | ||
| 157 | } | ||
| 158 | 152 | ||
| 159 | inline | 153 | inline uint8_t matrix_cols(void) { return MATRIX_COLS; } |
| 160 | uint8_t matrix_cols(void) | ||
| 161 | { | ||
| 162 | return MATRIX_COLS; | ||
| 163 | } | ||
| 164 | 154 | ||
| 165 | 155 | ||
| 166 | void matrix_init(void) | 156 | void 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. |
| 209 | matrix_row_t debounce_mask(matrix_row_t rawcols, uint8_t row) { | 196 | static 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 | ||
| 226 | matrix_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 | ||
| 235 | uint8_t matrix_scan(void) | ||
| 236 | { | ||
| 237 | // TODO: Find what is trashing interrupts | ||
| 238 | enableInterrupts(); | ||
| 239 | 206 | ||
| 240 | // First we handle the mouse inputs | 207 | uint8_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 | ||
| 341 | inline | 318 | inline bool matrix_is_on(uint8_t row, uint8_t col) { return (matrix[row] & ((matrix_row_t)1 << col)); } |
| 342 | bool matrix_is_on(uint8_t row, uint8_t col) | ||
| 343 | { | ||
| 344 | return (matrix[row] & ((matrix_row_t)1<<col)); | ||
| 345 | } | ||
| 346 | 319 | ||
| 347 | inline | 320 | inline matrix_row_t matrix_get_row(uint8_t row) { return matrix[row]; } |
| 348 | matrix_row_t matrix_get_row(uint8_t row) | ||
| 349 | { | ||
| 350 | return matrix[row]; | ||
| 351 | } | ||
| 352 | 321 | ||
| 353 | void matrix_print(void) | 322 | void 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 | ||
| 363 | uint8_t matrix_key_count(void) | 331 | uint8_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 |
| 373 | static void init_cols(void) | 340 | static 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 | ||
| 383 | static matrix_row_t read_cols(uint8_t row) | 349 | static 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 | } |
