X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=keyboards%2Fergodox_ez%2Fmatrix.c;h=2bfe27b9a300411a095d4d255fd5db128b6b09a9;hb=e717dcaa09143615ae0b46bf625621f67a7b55ce;hp=f0550e9b885e67858ba9558a8f640aea078dd690;hpb=0bd453b5276714b9a33c6a2060851ea5184c52b2;p=qmk_firmware.git diff --git a/keyboards/ergodox_ez/matrix.c b/keyboards/ergodox_ez/matrix.c index f0550e9b8..2bfe27b9a 100644 --- a/keyboards/ergodox_ez/matrix.c +++ b/keyboards/ergodox_ez/matrix.c @@ -1,9 +1,5 @@ /* -Note for ErgoDox EZ customizers: Here be dragons! -This is not a file you want to be messing with. -All of the interesting stuff for you is under keymaps/ :) -Love, Erez Copyright 2013 Oleg Kostyuk @@ -33,15 +29,14 @@ along with this program. If not, see . #include "debug.h" #include "util.h" #include "matrix.h" +#include "debounce.h" #include QMK_KEYBOARD_H -#include "i2cmaster.h" #ifdef DEBUG_MATRIX_SCAN_RATE -#include "timer.h" +# include "timer.h" #endif /* - * This constant define not debouncing time in msecs, but amount of matrix - * scan loops which should be made to get stable debounced results. + * This constant define not debouncing time in msecs, assuming eager_pr. * * On Ergodox matrix scan rate is relatively low, because of slow I2C. * Now it's only 317 scans/second, or about 3.15 msec/scan. @@ -53,217 +48,170 @@ along with this program. If not, see . */ #ifndef DEBOUNCE -# define DEBOUNCE 5 +# define DEBOUNCE 5 #endif /* matrix state(1:on, 0:off) */ -static matrix_row_t matrix[MATRIX_ROWS]; - -// Debouncing: store for each key the number of scans until it's eligible to -// change. When scanning the matrix, ignore any changes in keys that have -// already changed in the last DEBOUNCE scans. -static uint8_t debounce_matrix[MATRIX_ROWS * MATRIX_COLS]; +static matrix_row_t raw_matrix[MATRIX_ROWS]; // raw values +static matrix_row_t matrix[MATRIX_ROWS]; // debounced values static matrix_row_t read_cols(uint8_t row); -static void init_cols(void); -static void unselect_rows(void); -static void select_row(uint8_t row); +static void init_cols(void); +static void unselect_rows(void); +static void select_row(uint8_t row); static uint8_t mcp23018_reset_loop; +// static uint16_t mcp23018_reset_loop; #ifdef DEBUG_MATRIX_SCAN_RATE uint32_t matrix_timer; uint32_t matrix_scan_count; #endif +__attribute__((weak)) void matrix_init_user(void) {} -__attribute__ ((weak)) -void matrix_init_user(void) {} +__attribute__((weak)) void matrix_scan_user(void) {} -__attribute__ ((weak)) -void matrix_scan_user(void) {} +__attribute__((weak)) void matrix_init_kb(void) { matrix_init_user(); } -__attribute__ ((weak)) -void matrix_init_kb(void) { - matrix_init_user(); -} +__attribute__((weak)) void matrix_scan_kb(void) { matrix_scan_user(); } -__attribute__ ((weak)) -void matrix_scan_kb(void) { - matrix_scan_user(); -} +inline uint8_t matrix_rows(void) { return MATRIX_ROWS; } -inline -uint8_t matrix_rows(void) -{ - return MATRIX_ROWS; -} +inline uint8_t matrix_cols(void) { return MATRIX_COLS; } -inline -uint8_t matrix_cols(void) -{ - return MATRIX_COLS; -} +void matrix_init(void) { + // initialize row and col -void matrix_init(void) -{ - // initialize row and col + mcp23018_status = init_mcp23018(); - mcp23018_status = init_mcp23018(); + unselect_rows(); + init_cols(); - - unselect_rows(); - init_cols(); - - // initialize matrix state: all keys off - for (uint8_t i=0; i < MATRIX_ROWS; i++) { - matrix[i] = 0; - for (uint8_t j=0; j < MATRIX_COLS; ++j) { - debounce_matrix[i * MATRIX_COLS + j] = 0; - } - } + // initialize matrix state: all keys off + for (uint8_t i = 0; i < MATRIX_ROWS; i++) { + matrix[i] = 0; + raw_matrix[i] = 0; + } #ifdef DEBUG_MATRIX_SCAN_RATE - matrix_timer = timer_read32(); - matrix_scan_count = 0; + matrix_timer = timer_read32(); + matrix_scan_count = 0; #endif - - matrix_init_quantum(); - + debounce_init(MATRIX_ROWS); + matrix_init_quantum(); } void matrix_power_up(void) { - mcp23018_status = init_mcp23018(); + mcp23018_status = init_mcp23018(); - unselect_rows(); - init_cols(); + unselect_rows(); + init_cols(); - // initialize matrix state: all keys off - for (uint8_t i=0; i < MATRIX_ROWS; i++) { - matrix[i] = 0; - } + // initialize matrix state: all keys off + for (uint8_t i = 0; i < MATRIX_ROWS; i++) { + matrix[i] = 0; + } #ifdef DEBUG_MATRIX_SCAN_RATE - matrix_timer = timer_read32(); - matrix_scan_count = 0; + matrix_timer = timer_read32(); + matrix_scan_count = 0; #endif } -// Returns a matrix_row_t whose bits are set if the corresponding key should be -// eligible to change in this scan. -matrix_row_t debounce_mask(uint8_t row) { - matrix_row_t result = 0; - for (uint8_t j=0; j < MATRIX_COLS; ++j) { - if (debounce_matrix[row * MATRIX_COLS + j]) { - --debounce_matrix[row * MATRIX_COLS + j]; - } else { - result |= (1 << j); - } +// Reads and stores a row, returning +// whether a change occurred. +static inline bool store_raw_matrix_row(uint8_t index) { + matrix_row_t temp = read_cols(index); + if (raw_matrix[index] != temp) { + raw_matrix[index] = temp; + return true; } - return result; + return false; } -// Report changed keys in the given row. Resets the debounce countdowns -// corresponding to each set bit in 'change' to DEBOUNCE. -void debounce_report(matrix_row_t change, uint8_t row) { - for (uint8_t i = 0; i < MATRIX_COLS; ++i) { - if (change & (1 << i)) { - debounce_matrix[row * MATRIX_COLS + i] = DEBOUNCE; +uint8_t matrix_scan(void) { + if (mcp23018_status) { // if there was an error + if (++mcp23018_reset_loop == 0) { + // if (++mcp23018_reset_loop >= 1300) { + // since mcp23018_reset_loop is 8 bit - we'll try to reset once in 255 matrix scans + // this will be approx bit more frequent than once per second + print("trying to reset mcp23018\n"); + mcp23018_status = init_mcp23018(); + if (mcp23018_status) { + print("left side not responding\n"); + } else { + print("left side attached\n"); + ergodox_blink_all_leds(); + } } } -} - -uint8_t matrix_scan(void) -{ - if (mcp23018_status) { // if there was an error - if (++mcp23018_reset_loop == 0) { - // since mcp23018_reset_loop is 8 bit - we'll try to reset once in 255 matrix scans - // this will be approx bit more frequent than once per second - print("trying to reset mcp23018\n"); - mcp23018_status = init_mcp23018(); - if (mcp23018_status) { - print("left side not responding\n"); - } else { - print("left side attached\n"); - ergodox_blink_all_leds(); - } - } - } #ifdef DEBUG_MATRIX_SCAN_RATE - matrix_scan_count++; + matrix_scan_count++; - uint32_t timer_now = timer_read32(); - if (TIMER_DIFF_32(timer_now, matrix_timer)>1000) { - print("matrix scan frequency: "); - pdec(matrix_scan_count); - print("\n"); + uint32_t timer_now = timer_read32(); + if (TIMER_DIFF_32(timer_now, matrix_timer) > 1000) { + print("matrix scan frequency: "); + pdec(matrix_scan_count); + print("\n"); - matrix_timer = timer_now; - matrix_scan_count = 0; - } + matrix_timer = timer_now; + matrix_scan_count = 0; + } #endif #ifdef LEFT_LEDS - mcp23018_status = ergodox_left_leds_update(); -#endif // LEFT_LEDS - for (uint8_t i = 0; i < MATRIX_ROWS_PER_SIDE; i++) { - select_row(i); - // and select on left hand - select_row(i + MATRIX_ROWS_PER_SIDE); - // we don't need a 30us delay anymore, because selecting a - // left-hand row requires more than 30us for i2c. - matrix_row_t mask = debounce_mask(i); - matrix_row_t cols = (read_cols(i) & mask) | (matrix[i] & ~mask); - debounce_report(cols ^ matrix[i], i); - matrix[i] = cols; - // grab cols from right hand - mask = debounce_mask(i + MATRIX_ROWS_PER_SIDE); - cols = (read_cols(i + MATRIX_ROWS_PER_SIDE) & mask) | (matrix[i + MATRIX_ROWS_PER_SIDE] & ~mask); - debounce_report(cols ^ matrix[i + MATRIX_ROWS_PER_SIDE], i + MATRIX_ROWS_PER_SIDE); - matrix[i + MATRIX_ROWS_PER_SIDE] = cols; - unselect_rows(); - } + mcp23018_status = ergodox_left_leds_update(); +#endif // LEFT_LEDS + bool changed = false; + for (uint8_t i = 0; i < MATRIX_ROWS_PER_SIDE; i++) { + // select rows from left and right hands + uint8_t left_index = i; + uint8_t right_index = i + MATRIX_ROWS_PER_SIDE; + select_row(left_index); + select_row(right_index); + + // we don't need a 30us delay anymore, because selecting a + // left-hand row requires more than 30us for i2c. + + changed |= store_raw_matrix_row(left_index); + changed |= store_raw_matrix_row(right_index); - matrix_scan_quantum(); + unselect_rows(); + } - return 1; -} + debounce(raw_matrix, matrix, MATRIX_ROWS, changed); + matrix_scan_quantum(); -bool matrix_is_modified(void) // deprecated and evidently not called. -{ - return true; + return 1; } -inline -bool matrix_is_on(uint8_t row, uint8_t col) +bool matrix_is_modified(void) // deprecated and evidently not called. { - return (matrix[row] & ((matrix_row_t)1<> 2)); + uint8_t data = 0; + mcp23018_status = i2c_start(I2C_ADDR_WRITE, ERGODOX_EZ_I2C_TIMEOUT); + if (mcp23018_status) goto out; + mcp23018_status = i2c_write(GPIOB, ERGODOX_EZ_I2C_TIMEOUT); + if (mcp23018_status) goto out; + mcp23018_status = i2c_start(I2C_ADDR_READ, ERGODOX_EZ_I2C_TIMEOUT); + if (mcp23018_status) goto out; + mcp23018_status = i2c_read_nack(ERGODOX_EZ_I2C_TIMEOUT); + if (mcp23018_status < 0) goto out; + data = ~((uint8_t)mcp23018_status); + mcp23018_status = I2C_STATUS_SUCCESS; + out: + i2c_stop(); + return data; } + } else { + /* read from teensy + * bitmask is 0b11110011, but we want those all + * in the lower six bits. + * we'll return 1s for the top two, but that's harmless. + */ + + return ~((PINF & 0x03) | ((PINF & 0xF0) >> 2)); + } } /* Row pin configuration @@ -324,78 +275,70 @@ static matrix_row_t read_cols(uint8_t row) * row: 0 1 2 3 4 5 6 * pin: A0 A1 A2 A3 A4 A5 A6 */ -static void unselect_rows(void) -{ - // unselect on mcp23018 - if (mcp23018_status) { // if there was an error - // do nothing - } else { - // set all rows hi-Z : 1 - mcp23018_status = i2c_start(I2C_ADDR_WRITE); if (mcp23018_status) goto out; - mcp23018_status = i2c_write(GPIOA); if (mcp23018_status) goto out; - mcp23018_status = i2c_write(0xFF); if (mcp23018_status) goto out; - out: - i2c_stop(); - } - - // unselect on teensy - // Hi-Z(DDR:0, PORT:0) to unselect - DDRB &= ~(1<<0 | 1<<1 | 1<<2 | 1<<3); - PORTB &= ~(1<<0 | 1<<1 | 1<<2 | 1<<3); - DDRD &= ~(1<<2 | 1<<3); - PORTD &= ~(1<<2 | 1<<3); - DDRC &= ~(1<<6); - PORTC &= ~(1<<6); +static void unselect_rows(void) { + // no need to unselect on mcp23018, because the select step sets all + // the other row bits high, and it's not changing to a different + // direction + + // unselect on teensy + // Hi-Z(DDR:0, PORT:0) to unselect + DDRB &= ~(1 << 0 | 1 << 1 | 1 << 2 | 1 << 3); + PORTB &= ~(1 << 0 | 1 << 1 | 1 << 2 | 1 << 3); + DDRD &= ~(1 << 2 | 1 << 3); + PORTD &= ~(1 << 2 | 1 << 3); + DDRC &= ~(1 << 6); + PORTC &= ~(1 << 6); } -static void select_row(uint8_t row) -{ - if (row < 7) { - // select on mcp23018 - if (mcp23018_status) { // if there was an error - // do nothing - } else { - // set active row low : 0 - // set other rows hi-Z : 1 - mcp23018_status = i2c_start(I2C_ADDR_WRITE); if (mcp23018_status) goto out; - mcp23018_status = i2c_write(GPIOA); if (mcp23018_status) goto out; - mcp23018_status = i2c_write(0xFF & ~(1<