X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=quantum%2Fsplit_common%2Fmatrix.c;h=f2a277c69f3a698de4ecb16220617e264960172c;hb=030faf951cb99840394c56803958f249383e9362;hp=ff6738b58f4ce0bba6b214b01558ec1205c0f1d7;hpb=96c9ebc2e48b8f327bca2a2d5db77c0ab2ef6c8a;p=qmk_firmware.git diff --git a/quantum/split_common/matrix.c b/quantum/split_common/matrix.c index ff6738b58..f2a277c69 100644 --- a/quantum/split_common/matrix.c +++ b/quantum/split_common/matrix.c @@ -20,517 +20,309 @@ 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" +#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) +#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 -#ifndef DEBOUNCING_DELAY -# define DEBOUNCING_DELAY 5 -#endif +#define ERROR_DISCONNECT_COUNT 5 -#if (DEBOUNCING_DELAY > 0) - static uint16_t debouncing_time; - static bool debouncing = false; -#endif +#define ROWS_PER_HAND (MATRIX_ROWS / 2) -#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) +#ifdef DIRECT_PINS +static pin_t direct_pins[MATRIX_ROWS][MATRIX_COLS] = DIRECT_PINS; #else -# error "Currently only supports 8 COLS" +static pin_t row_pins[MATRIX_ROWS] = MATRIX_ROW_PINS; +static pin_t col_pins[MATRIX_COLS] = MATRIX_COL_PINS; #endif -static matrix_row_t matrix_debouncing[MATRIX_ROWS]; -#define ERROR_DISCONNECT_COUNT 5 +/* matrix state(1:on, 0:off) */ +static matrix_row_t matrix[MATRIX_ROWS]; +static matrix_row_t raw_matrix[ROWS_PER_HAND]; -#define ROWS_PER_HAND (MATRIX_ROWS/2) +// row offsets for each hand +uint8_t thisHand, thatHand; -static uint8_t error_count = 0; +// user-defined overridable functions -static uint8_t row_pins[MATRIX_ROWS] = MATRIX_ROW_PINS; -static uint8_t col_pins[MATRIX_COLS] = MATRIX_COL_PINS; +__attribute__((weak)) void matrix_init_kb(void) { matrix_init_user(); } -/* 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 +__attribute__((weak)) void matrix_scan_kb(void) { matrix_scan_user(); } -__attribute__ ((weak)) -void matrix_init_kb(void) { - matrix_init_user(); -} +__attribute__((weak)) void matrix_init_user(void) {} -__attribute__ ((weak)) -void matrix_scan_kb(void) { - matrix_scan_user(); -} +__attribute__((weak)) void matrix_scan_user(void) {} -__attribute__ ((weak)) -void matrix_init_user(void) { -} +__attribute__((weak)) void matrix_slave_scan_user(void) {} -__attribute__ ((weak)) -void matrix_scan_user(void) { -} +// helper functions -__attribute__ ((weak)) -void matrix_slave_scan_user(void) { -} +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; +bool matrix_is_modified(void) { + if (debounce_active()) return false; + return true; } -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); +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; +} - if (matrix_changed) { - debouncing = true; - debouncing_time = timer_read(); - } +// matrix code -# else - read_cols_on_row(matrix+offset, current_row); -# endif +#ifdef DIRECT_PINS +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); + } } + } +} -#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 +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; + 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); } -#endif - -# 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 + } - return 1; + return (last_row_value != current_matrix[current_row]); } -#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; +#elif (DIODE_DIRECTION == COL2ROW) - // start of matrix stored at I2C_KEYMAP_START - err = i2c_master_write(I2C_KEYMAP_START); - if (err) goto i2c_error; +static void select_row(uint8_t row) { + setPinOutput(row_pins[row]); + writePinLow(row_pins[row]); +} - // Start read - err = i2c_master_start(SLAVE_I2C_ADDRESS + I2C_READ); - if (err) goto i2c_error; +static void unselect_row(uint8_t row) { setPinInputHigh(row_pins[row]); } - 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; - } - - #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; +static void unselect_rows(void) { + for (uint8_t x = 0; x < ROWS_PER_HAND; x++) { + setPinInputHigh(row_pins[x]); + } } -#else // USE_SERIAL - -int serial_transaction(void) { - int slaveOffset = (isLeftHand) ? (ROWS_PER_HAND) : 0; +static void init_pins(void) { + unselect_rows(); + for (uint8_t x = 0; x < MATRIX_COLS; x++) { + setPinInputHigh(col_pins[x]); + } +} - if (serial_update_buffers()) { - return 1; - } +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]; - 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; -} -#endif + // Clear data in matrix row + current_matrix[current_row] = 0; -uint8_t matrix_scan(void) -{ - uint8_t ret = _matrix_scan(); + // Select row and wait for row selecton to stabilize + select_row(current_row); + wait_us(30); -#if defined(USE_I2C) || defined(EH) - if( i2c_transaction() ) { -#else // USE_SERIAL - if( serial_transaction() ) { -#endif + // 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); + } - error_count++; + // Unselect row + unselect_row(current_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; + return (last_row_value != current_matrix[current_row]); } -void matrix_slave_scan(void) { - _matrix_scan(); - - int offset = (isLeftHand) ? 0 : ROWS_PER_HAND; +#elif (DIODE_DIRECTION == ROW2COL) -#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 - matrix_slave_scan_user(); +static void select_col(uint8_t col) { + setPinOutput(col_pins[col]); + writePinLow(col_pins[col]); } -bool matrix_is_modified(void) -{ - if (debouncing) return false; - return true; -} +static void unselect_col(uint8_t col) { setPinInputHigh(col_pins[col]); } -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 + // 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); } -} -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]; + // Determine if the matrix changed state + if ((last_row_value != current_matrix[row_index]) && !(matrix_changed)) { + matrix_changed = true; + } + } - // Clear data in matrix row - current_matrix[current_row] = 0; + // Unselect col + unselect_col(current_col); - // Select row and wait for row selecton to stabilize - select_row(current_row); - wait_us(30); + return matrix_changed; +} - // For each col... - for(uint8_t col_index = 0; col_index < MATRIX_COLS; col_index++) { +#endif - // 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)); +void matrix_init(void) { + debug_enable = true; + debug_matrix = true; + debug_mouse = true; - // Populate the matrix row with the state of the col pin - current_matrix[current_row] |= pin_state ? 0 : (ROW_SHIFTER << col_index); + // 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]; + } +#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 + } - // Unselect row - unselect_row(current_row); + thisHand = isLeftHand ? 0 : (ROWS_PER_HAND); + thatHand = ROWS_PER_HAND - thisHand; - return (last_row_value != current_matrix[current_row]); -} + // initialize key pins + init_pins(); -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 -} + // initialize matrix state: all keys off + for (uint8_t i = 0; i < MATRIX_ROWS; i++) { + matrix[i] = 0; + } -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 -} + debounce_init(ROWS_PER_HAND); -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 - } + matrix_init_quantum(); } -#elif (DIODE_DIRECTION == ROW2COL) +uint8_t _matrix_scan(void) { + bool changed = false; -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 - } -} +#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 -static bool read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col) -{ - bool matrix_changed = false; + debounce(raw_matrix, matrix + thisHand, ROWS_PER_HAND, changed); - // Select col and wait for col selecton to stabilize - select_col(current_col); - wait_us(30); + return 1; +} - // For each row... - for(uint8_t row_index = 0; row_index < ROWS_PER_HAND; row_index++) - { +uint8_t matrix_scan(void) { + uint8_t ret = _matrix_scan(); - // Store last value of row prior to reading - matrix_row_t last_row_value = current_matrix[row_index]; + if (is_keyboard_master()) { + static uint8_t error_count; - // 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); - } + if (!transport_master(matrix + thatHand)) { + error_count++; - // Determine if the matrix changed state - if ((last_row_value != current_matrix[row_index]) && !(matrix_changed)) - { - matrix_changed = true; + 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; } - // Unselect col - unselect_col(current_col); - - return matrix_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 -} - -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 -} + matrix_scan_quantum(); + } else { + transport_slave(matrix + thisHand); + matrix_slave_scan_user(); + } -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 - } + return ret; } - -#endif