X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;ds=sidebyside;f=quantum%2Fsplit_common%2Fmatrix.c;h=3c3daf3d3b5edaab02de617d6f6e96148c59e44d;hb=670a9b7f83dacf2b0e9fb42756935a77598c6677;hp=3d2983f2ef65bde79c64104cc4a0425317390c34;hpb=3dbdfbd99a9efd12275abdcdcf2abe843e300f6b;p=qmk_firmware.git diff --git a/quantum/split_common/matrix.c b/quantum/split_common/matrix.c index 3d2983f2e..3c3daf3d3 100644 --- a/quantum/split_common/matrix.c +++ b/quantum/split_common/matrix.c @@ -20,535 +20,315 @@ along with this program. If not, see . */ #include #include -#include #include "wait.h" -#include "print.h" -#include "debug.h" #include "util.h" #include "matrix.h" #include "split_util.h" -#include "pro_micro.h" #include "config.h" -#include "timer.h" -#include "split_flags.h" +#include "quantum.h" +#include "debounce.h" +#include "transport.h" -#ifdef RGBLIGHT_ENABLE -# include "rgblight.h" -#endif -#ifdef BACKLIGHT_ENABLE -# include "backlight.h" - extern backlight_config_t backlight_config; -#endif - -#if defined(USE_I2C) || defined(EH) -# include "i2c.h" -#else // USE_SERIAL -# include "serial.h" -#endif - -#ifndef DEBOUNCING_DELAY -# define DEBOUNCING_DELAY 5 -#endif - -#if (DEBOUNCING_DELAY > 0) - static uint16_t debouncing_time; - static bool debouncing = false; +#ifdef ENCODER_ENABLE + #include "encoder.h" #endif #if (MATRIX_COLS <= 8) -# define print_matrix_header() print("\nr/c 01234567\n") -# define print_matrix_row(row) print_bin_reverse8(matrix_get_row(row)) -# define matrix_bitpop(i) bitpop(matrix[i]) -# define ROW_SHIFTER ((uint8_t)1) -#else -# error "Currently only supports 8 COLS" +# define print_matrix_header() print("\nr/c 01234567\n") +# define print_matrix_row(row) print_bin_reverse8(matrix_get_row(row)) +# define matrix_bitpop(i) bitpop(matrix[i]) +# define ROW_SHIFTER ((uint8_t)1) +#elif (MATRIX_COLS <= 16) +# define print_matrix_header() print("\nr/c 0123456789ABCDEF\n") +# define print_matrix_row(row) print_bin_reverse16(matrix_get_row(row)) +# define matrix_bitpop(i) bitpop16(matrix[i]) +# define ROW_SHIFTER ((uint16_t)1) +#elif (MATRIX_COLS <= 32) +# define print_matrix_header() print("\nr/c 0123456789ABCDEF0123456789ABCDEF\n") +# define print_matrix_row(row) print_bin_reverse32(matrix_get_row(row)) +# define matrix_bitpop(i) bitpop32(matrix[i]) +# define ROW_SHIFTER ((uint32_t)1) #endif -static matrix_row_t matrix_debouncing[MATRIX_ROWS]; #define ERROR_DISCONNECT_COUNT 5 -#define ROWS_PER_HAND (MATRIX_ROWS/2) - -static uint8_t error_count = 0; +#define ROWS_PER_HAND (MATRIX_ROWS / 2) -static uint8_t row_pins[MATRIX_ROWS] = MATRIX_ROW_PINS; -static uint8_t col_pins[MATRIX_COLS] = MATRIX_COL_PINS; +#ifdef DIRECT_PINS +static pin_t direct_pins[MATRIX_ROWS][MATRIX_COLS] = DIRECT_PINS; +#else +static pin_t row_pins[MATRIX_ROWS] = MATRIX_ROW_PINS; +static pin_t col_pins[MATRIX_COLS] = MATRIX_COL_PINS; +#endif /* matrix state(1:on, 0:off) */ static matrix_row_t matrix[MATRIX_ROWS]; -static matrix_row_t matrix_debouncing[MATRIX_ROWS]; - -#if (DIODE_DIRECTION == COL2ROW) - static void init_cols(void); - static bool read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row); - static void unselect_rows(void); - static void select_row(uint8_t row); - static void unselect_row(uint8_t row); -#elif (DIODE_DIRECTION == ROW2COL) - static void init_rows(void); - static bool read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col); - static void unselect_cols(void); - static void unselect_col(uint8_t col); - static void select_col(uint8_t col); -#endif +static matrix_row_t raw_matrix[ROWS_PER_HAND]; -__attribute__ ((weak)) -void matrix_init_kb(void) { - matrix_init_user(); -} +// row offsets for each hand +uint8_t thisHand, thatHand; -__attribute__ ((weak)) -void matrix_scan_kb(void) { - matrix_scan_user(); -} +// user-defined overridable functions -__attribute__ ((weak)) -void matrix_init_user(void) { -} +__attribute__((weak)) void matrix_init_kb(void) { matrix_init_user(); } -__attribute__ ((weak)) -void matrix_scan_user(void) { -} +__attribute__((weak)) void matrix_scan_kb(void) { matrix_scan_user(); } -__attribute__ ((weak)) -void matrix_slave_scan_user(void) { -} +__attribute__((weak)) void matrix_init_user(void) {} -inline -uint8_t matrix_rows(void) -{ - return MATRIX_ROWS; -} +__attribute__((weak)) void matrix_scan_user(void) {} -inline -uint8_t matrix_cols(void) -{ - return MATRIX_COLS; -} +__attribute__((weak)) void matrix_slave_scan_user(void) {} -void matrix_init(void) -{ -#ifdef DISABLE_JTAG - // JTAG disable for PORT F. write JTD bit twice within four cycles. - MCUCR |= (1< 0) - bool matrix_changed = read_cols_on_row(matrix_debouncing+offset, current_row); - - if (matrix_changed) { - debouncing = true; - debouncing_time = timer_read(); - } - -# else - read_cols_on_row(matrix+offset, current_row); -# endif - - } - -#elif (DIODE_DIRECTION == ROW2COL) - // Set col, read rows - for (uint8_t current_col = 0; current_col < MATRIX_COLS; current_col++) { -# if (DEBOUNCING_DELAY > 0) - bool matrix_changed = read_rows_on_col(matrix_debouncing+offset, current_col); - if (matrix_changed) { - debouncing = true; - debouncing_time = timer_read(); - } -# else - read_rows_on_col(matrix+offset, current_col); -# endif +inline bool matrix_is_on(uint8_t row, uint8_t col) { return (matrix[row] & ((matrix_row_t)1 << col)); } - } -#endif +inline matrix_row_t matrix_get_row(uint8_t row) { return matrix[row]; } -# if (DEBOUNCING_DELAY > 0) - if (debouncing && (timer_elapsed(debouncing_time) > DEBOUNCING_DELAY)) { - for (uint8_t i = 0; i < ROWS_PER_HAND; i++) { - matrix[i+offset] = matrix_debouncing[i+offset]; - } - debouncing = false; - } -# endif +void matrix_print(void) { + print_matrix_header(); - return 1; + for (uint8_t row = 0; row < MATRIX_ROWS; row++) { + phex(row); + print(": "); + print_matrix_row(row); + print("\n"); + } } -#if defined(USE_I2C) || defined(EH) - -// Get rows from other half over i2c -int i2c_transaction(void) { - int slaveOffset = (isLeftHand) ? (ROWS_PER_HAND) : 0; - int err = 0; - - // write backlight info - #ifdef BACKLIGHT_ENABLE - if (BACKLIT_DIRTY) { - err = i2c_master_start(SLAVE_I2C_ADDRESS + I2C_WRITE); - if (err) goto i2c_error; - - // Backlight location - err = i2c_master_write(I2C_BACKLIT_START); - if (err) goto i2c_error; - - // Write backlight - i2c_master_write(get_backlight_level()); - - BACKLIT_DIRTY = false; - } - #endif - - err = i2c_master_start(SLAVE_I2C_ADDRESS + I2C_WRITE); - if (err) goto i2c_error; +uint8_t matrix_key_count(void) { + uint8_t count = 0; + for (uint8_t i = 0; i < MATRIX_ROWS; i++) { + count += matrix_bitpop(i); + } + return count; +} - // start of matrix stored at I2C_KEYMAP_START - err = i2c_master_write(I2C_KEYMAP_START); - if (err) goto i2c_error; +// matrix code - // Start read - err = i2c_master_start(SLAVE_I2C_ADDRESS + I2C_READ); - if (err) goto i2c_error; +#ifdef DIRECT_PINS - if (!err) { - int i; - for (i = 0; i < ROWS_PER_HAND-1; ++i) { - matrix[slaveOffset+i] = i2c_master_read(I2C_ACK); - } - matrix[slaveOffset+i] = i2c_master_read(I2C_NACK); - i2c_master_stop(); - } else { -i2c_error: // the cable is disconnceted, or something else went wrong - i2c_reset_state(); - return err; +static void init_pins(void) { + for (int row = 0; row < MATRIX_ROWS; row++) { + for (int col = 0; col < MATRIX_COLS; col++) { + pin_t pin = direct_pins[row][col]; + if (pin != NO_PIN) { + setPinInputHigh(pin); + } } - - #ifdef RGBLIGHT_ENABLE - if (RGB_DIRTY) { - err = i2c_master_start(SLAVE_I2C_ADDRESS + I2C_WRITE); - if (err) goto i2c_error; - - // RGB Location - err = i2c_master_write(I2C_RGB_START); - if (err) goto i2c_error; - - uint32_t dword = eeconfig_read_rgblight(); - - // Write RGB - err = i2c_master_write_data(&dword, 4); - if (err) goto i2c_error; - - RGB_DIRTY = false; - i2c_master_stop(); - } - #endif - - return 0; + } } -#else // USE_SERIAL +static bool read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row) { + matrix_row_t last_row_value = current_matrix[current_row]; + current_matrix[current_row] = 0; -int serial_transaction(void) { - int slaveOffset = (isLeftHand) ? (ROWS_PER_HAND) : 0; - - if (serial_update_buffers()) { - return 1; + for (uint8_t col_index = 0; col_index < MATRIX_COLS; col_index++) { + pin_t pin = direct_pins[current_row][col_index]; + if (pin != NO_PIN) { + current_matrix[current_row] |= readPin(pin) ? 0 : (ROW_SHIFTER << col_index); } + } - for (int i = 0; i < ROWS_PER_HAND; ++i) { - matrix[slaveOffset+i] = serial_slave_buffer[i]; - } - - #ifdef RGBLIGHT_ENABLE - // Code to send RGB over serial goes here (not implemented yet) - #endif - - #ifdef BACKLIGHT_ENABLE - // Write backlight level for slave to read - serial_master_buffer[SERIAL_BACKLIT_START] = backlight_config.enable ? backlight_config.level : 0; - #endif - - return 0; + return (last_row_value != current_matrix[current_row]); } -#endif -uint8_t matrix_scan(void) -{ - uint8_t ret = _matrix_scan(); +#elif (DIODE_DIRECTION == COL2ROW) -#if defined(USE_I2C) || defined(EH) - if( i2c_transaction() ) { -#else // USE_SERIAL - if( serial_transaction() ) { -#endif +static void select_row(uint8_t row) { + setPinOutput(row_pins[row]); + writePinLow(row_pins[row]); +} - error_count++; +static void unselect_row(uint8_t row) { setPinInputHigh(row_pins[row]); } - if (error_count > ERROR_DISCONNECT_COUNT) { - // reset other half if disconnected - int slaveOffset = (isLeftHand) ? (ROWS_PER_HAND) : 0; - for (int i = 0; i < ROWS_PER_HAND; ++i) { - matrix[slaveOffset+i] = 0; - } - } - } else { - error_count = 0; - } - matrix_scan_quantum(); - return ret; +static void unselect_rows(void) { + for (uint8_t x = 0; x < ROWS_PER_HAND; x++) { + setPinInputHigh(row_pins[x]); + } } -void matrix_slave_scan(void) { - _matrix_scan(); +static void init_pins(void) { + unselect_rows(); + for (uint8_t x = 0; x < MATRIX_COLS; x++) { + setPinInputHigh(col_pins[x]); + } +} - int offset = (isLeftHand) ? 0 : ROWS_PER_HAND; +static bool read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row) { + // Store last value of row prior to reading + matrix_row_t last_row_value = current_matrix[current_row]; -#if defined(USE_I2C) || defined(EH) - for (int i = 0; i < ROWS_PER_HAND; ++i) { - i2c_slave_buffer[I2C_KEYMAP_START+i] = matrix[offset+i]; - } -#else // USE_SERIAL - for (int i = 0; i < ROWS_PER_HAND; ++i) { - serial_slave_buffer[i] = matrix[offset+i]; - } -#endif -#ifdef USE_I2C -#ifdef BACKLIGHT_ENABLE - // Read backlight level sent from master and update level on slave - backlight_set(i2c_slave_buffer[0]); -#endif - for (int i = 0; i < ROWS_PER_HAND; ++i) { - i2c_slave_buffer[i+1] = matrix[offset+i]; - } -#else // USE_SERIAL - for (int i = 0; i < ROWS_PER_HAND; ++i) { - serial_slave_buffer[i] = matrix[offset+i]; - } + // Clear data in matrix row + current_matrix[current_row] = 0; -#ifdef BACKLIGHT_ENABLE - // Read backlight level sent from master and update level on slave - backlight_set(serial_master_buffer[SERIAL_BACKLIT_START]); -#endif -#endif - matrix_slave_scan_user(); -} + // Select row and wait for row selecton to stabilize + select_row(current_row); + wait_us(30); -bool matrix_is_modified(void) -{ - if (debouncing) return false; - return true; -} + // For each col... + for (uint8_t col_index = 0; col_index < MATRIX_COLS; col_index++) { + // Populate the matrix row with the state of the col pin + current_matrix[current_row] |= readPin(col_pins[col_index]) ? 0 : (ROW_SHIFTER << col_index); + } -inline -bool matrix_is_on(uint8_t row, uint8_t col) -{ - return (matrix[row] & ((matrix_row_t)1<> 4) + 1) &= ~_BV(pin & 0xF); // IN - _SFR_IO8((pin >> 4) + 2) |= _BV(pin & 0xF); // HI - } +static void unselect_cols(void) { + for (uint8_t x = 0; x < MATRIX_COLS; x++) { + setPinInputHigh(col_pins[x]); + } } -static bool read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row) -{ - // Store last value of row prior to reading - matrix_row_t last_row_value = current_matrix[current_row]; +static void init_pins(void) { + unselect_cols(); + for (uint8_t x = 0; x < ROWS_PER_HAND; x++) { + setPinInputHigh(row_pins[x]); + } +} - // Clear data in matrix row - current_matrix[current_row] = 0; +static bool read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col) { + bool matrix_changed = false; - // Select row and wait for row selecton to stabilize - select_row(current_row); - wait_us(30); + // Select col and wait for col selecton to stabilize + select_col(current_col); + wait_us(30); - // For each col... - for(uint8_t col_index = 0; col_index < MATRIX_COLS; col_index++) { + // For each row... + for (uint8_t row_index = 0; row_index < ROWS_PER_HAND; row_index++) { + // Store last value of row prior to reading + matrix_row_t last_row_value = current_matrix[row_index]; - // Select the col pin to read (active low) - uint8_t pin = col_pins[col_index]; - uint8_t pin_state = (_SFR_IO8(pin >> 4) & _BV(pin & 0xF)); + // Check row pin state + if (readPin(row_pins[row_index])) { + // Pin HI, clear col bit + current_matrix[row_index] &= ~(ROW_SHIFTER << current_col); + } else { + // Pin LO, set col bit + current_matrix[row_index] |= (ROW_SHIFTER << current_col); + } - // Populate the matrix row with the state of the col pin - current_matrix[current_row] |= pin_state ? 0 : (ROW_SHIFTER << col_index); + // Determine if the matrix changed state + if ((last_row_value != current_matrix[row_index]) && !(matrix_changed)) { + matrix_changed = true; } + } - // Unselect row - unselect_row(current_row); + // Unselect col + unselect_col(current_col); - return (last_row_value != current_matrix[current_row]); + return matrix_changed; } -static void select_row(uint8_t row) -{ - uint8_t pin = row_pins[row]; - _SFR_IO8((pin >> 4) + 1) |= _BV(pin & 0xF); // OUT - _SFR_IO8((pin >> 4) + 2) &= ~_BV(pin & 0xF); // LOW -} +#endif -static void unselect_row(uint8_t row) -{ - uint8_t pin = row_pins[row]; - _SFR_IO8((pin >> 4) + 1) &= ~_BV(pin & 0xF); // IN - _SFR_IO8((pin >> 4) + 2) |= _BV(pin & 0xF); // HI -} +void matrix_init(void) { + debug_enable = true; + debug_matrix = true; + debug_mouse = true; -static void unselect_rows(void) -{ - for(uint8_t x = 0; x < ROWS_PER_HAND; x++) { - uint8_t pin = row_pins[x]; - _SFR_IO8((pin >> 4) + 1) &= ~_BV(pin & 0xF); // IN - _SFR_IO8((pin >> 4) + 2) |= _BV(pin & 0xF); // HI + // Set pinout for right half if pinout for that half is defined + if (!isLeftHand) { +#ifdef MATRIX_ROW_PINS_RIGHT + const uint8_t row_pins_right[MATRIX_ROWS] = MATRIX_ROW_PINS_RIGHT; + for (uint8_t i = 0; i < MATRIX_ROWS; i++) { + row_pins[i] = row_pins_right[i]; } -} - -#elif (DIODE_DIRECTION == ROW2COL) - -static void init_rows(void) -{ - for(uint8_t x = 0; x < ROWS_PER_HAND; x++) { - uint8_t pin = row_pins[x]; - _SFR_IO8((pin >> 4) + 1) &= ~_BV(pin & 0xF); // IN - _SFR_IO8((pin >> 4) + 2) |= _BV(pin & 0xF); // HI +#endif +#ifdef MATRIX_COL_PINS_RIGHT + const uint8_t col_pins_right[MATRIX_COLS] = MATRIX_COL_PINS_RIGHT; + for (uint8_t i = 0; i < MATRIX_COLS; i++) { + col_pins[i] = col_pins_right[i]; } -} +#endif + } -static bool read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col) -{ - bool matrix_changed = false; + thisHand = isLeftHand ? 0 : (ROWS_PER_HAND); + thatHand = ROWS_PER_HAND - thisHand; - // Select col and wait for col selecton to stabilize - select_col(current_col); - wait_us(30); + // initialize key pins + init_pins(); - // For each row... - for(uint8_t row_index = 0; row_index < ROWS_PER_HAND; row_index++) - { + // initialize matrix state: all keys off + for (uint8_t i = 0; i < MATRIX_ROWS; i++) { + matrix[i] = 0; + } - // Store last value of row prior to reading - matrix_row_t last_row_value = current_matrix[row_index]; + debounce_init(ROWS_PER_HAND); - // Check row pin state - if ((_SFR_IO8(row_pins[row_index] >> 4) & _BV(row_pins[row_index] & 0xF)) == 0) - { - // Pin LO, set col bit - current_matrix[row_index] |= (ROW_SHIFTER << current_col); - } - else - { - // Pin HI, clear col bit - current_matrix[row_index] &= ~(ROW_SHIFTER << current_col); - } + matrix_init_quantum(); +} - // Determine if the matrix changed state - if ((last_row_value != current_matrix[row_index]) && !(matrix_changed)) - { - matrix_changed = true; - } - } +uint8_t _matrix_scan(void) { + bool changed = false; - // Unselect col - unselect_col(current_col); +#if defined(DIRECT_PINS) || (DIODE_DIRECTION == COL2ROW) + // Set row, read cols + for (uint8_t current_row = 0; current_row < ROWS_PER_HAND; current_row++) { + changed |= read_cols_on_row(raw_matrix, current_row); + } +#elif (DIODE_DIRECTION == ROW2COL) + // Set col, read rows + for (uint8_t current_col = 0; current_col < MATRIX_COLS; current_col++) { + changed |= read_rows_on_col(raw_matrix, current_col); + } +#endif - return matrix_changed; -} + debounce(raw_matrix, matrix + thisHand, ROWS_PER_HAND, changed); -static void select_col(uint8_t col) -{ - uint8_t pin = col_pins[col]; - _SFR_IO8((pin >> 4) + 1) |= _BV(pin & 0xF); // OUT - _SFR_IO8((pin >> 4) + 2) &= ~_BV(pin & 0xF); // LOW + return (uint8_t)changed; } -static void unselect_col(uint8_t col) -{ - uint8_t pin = col_pins[col]; - _SFR_IO8((pin >> 4) + 1) &= ~_BV(pin & 0xF); // IN - _SFR_IO8((pin >> 4) + 2) |= _BV(pin & 0xF); // HI -} +uint8_t matrix_scan(void) { + uint8_t ret = _matrix_scan(); -static void unselect_cols(void) -{ - for(uint8_t x = 0; x < MATRIX_COLS; x++) { - uint8_t pin = col_pins[x]; - _SFR_IO8((pin >> 4) + 1) &= ~_BV(pin & 0xF); // IN - _SFR_IO8((pin >> 4) + 2) |= _BV(pin & 0xF); // HI + if (is_keyboard_master()) { + static uint8_t error_count; + + if (!transport_master(matrix + thatHand)) { + error_count++; + + if (error_count > ERROR_DISCONNECT_COUNT) { + // reset other half if disconnected + for (int i = 0; i < ROWS_PER_HAND; ++i) { + matrix[thatHand + i] = 0; + } + } + } else { + error_count = 0; } -} + matrix_scan_quantum(); + } else { + transport_slave(matrix + thisHand); +#ifdef ENCODER_ENABLE + encoder_read(); #endif + matrix_slave_scan_user(); + } + + return ret; +}