diff --git a/drivers/gpio/pca9555.c b/drivers/gpio/pca9555.c index 496bbca04..02b5abbdd 100644 --- a/drivers/gpio/pca9555.c +++ b/drivers/gpio/pca9555.c @@ -76,3 +76,20 @@ uint8_t pca9555_readPins(uint8_t slave_addr, uint8_t port) { } return data; } + +uint16_t pca9555_readAllPins(uint8_t slave_addr) { + uint8_t addr = SLAVE_TO_ADDR(slave_addr); + + typedef union { + uint8_t u8[2]; + uint16_t u16; + } data16; + + data16 data; + + i2c_status_t ret = i2c_readReg(addr, CMD_INPUT_0, &data.u8[0], sizeof(data), TIMEOUT); + if (ret != I2C_STATUS_SUCCESS) { + print("pca9555_readAllPins::FAILED\n"); + } + return data.u16; +} diff --git a/drivers/gpio/pca9555.h b/drivers/gpio/pca9555.h index ebb97e2f3..3341ec3eb 100644 --- a/drivers/gpio/pca9555.h +++ b/drivers/gpio/pca9555.h @@ -53,3 +53,5 @@ void pca9555_set_config(uint8_t slave_addr, uint8_t port, uint8_t conf); void pca9555_set_output(uint8_t slave_addr, uint8_t port, uint8_t conf); uint8_t pca9555_readPins(uint8_t slave_addr, uint8_t port); + +uint16_t pca9555_readAllPins(uint8_t slave_addr); diff --git a/keyboards/xd84/matrix.c b/keyboards/xd84/matrix.c index 4cb5544ca..a4ddbee9a 100644 --- a/keyboards/xd84/matrix.c +++ b/keyboards/xd84/matrix.c @@ -30,65 +30,69 @@ //_____Utility funcs___________________________________________________________ static void init_pins(void) { - // init all cols high - IC2 all input - pca9555_set_config(IC2, PCA9555_PORT0, ALL_INPUT);//same as initial state - pca9555_set_config(IC2, PCA9555_PORT1, ALL_INPUT);//same as initial state + // init all cols high - IC2 all input + pca9555_set_config(IC2, PCA9555_PORT0, ALL_INPUT); // same as initial state + pca9555_set_config(IC2, PCA9555_PORT1, ALL_INPUT); // same as initial state - // init all rows - IC1 port0 input - pca9555_set_config(IC1, PCA9555_PORT0, ALL_INPUT);//same as initial state + // init all rows - IC1 port0 input + pca9555_set_config(IC1, PCA9555_PORT0, ALL_INPUT); // same as initial state + pca9555_set_output(IC1, PCA9555_PORT0, ALL_LOW); } static void select_row(uint8_t row) { - // For the XD84 all rows are on the same IC and port - // so its safe enough to assume here row == pin - uint8_t pin = row; - uint8_t mask = 1 << pin; + // For the XD84 all rows are on the same IC and port + // so its safe enough to assume here row == pin + uint8_t pin = row; + uint8_t mask = 1 << pin; - pca9555_set_output(IC1, PCA9555_PORT0, ALL_HIGH & (~mask)); - pca9555_set_config(IC1, PCA9555_PORT0, ALL_INPUT & (~mask)); + // we configure output once in init, as pca9555 remembers state when flipping between input/output + // pca9555_set_output(IC1, PCA9555_PORT0, ALL_HIGH & (~mask)); + pca9555_set_config(IC1, PCA9555_PORT0, ALL_INPUT & (~mask)); } static uint16_t read_cols(void) { - uint16_t state_1 = pca9555_readPins(IC2, PCA9555_PORT0); - uint16_t state_2 = pca9555_readPins(IC2, PCA9555_PORT1); + // uint16_t state_1 = pca9555_readPins(IC2, PCA9555_PORT0); + // uint16_t state_2 = pca9555_readPins(IC2, PCA9555_PORT1); + uint16_t state = pca9555_readAllPins(IC2); - // For the XD84 all cols are on the same IC and mapped sequentially - // while this technically gives 16 column reads, - // the 16th column can never be set so is safely ignored - return ~((state_2 << 8) | state_1); + // For the XD84 all cols are on the same IC and mapped sequentially + // while this technically gives 16 column reads, + // the 16th column can never be set so is safely ignored + // return ~((state_2 << 8) | state_1); + return ~state; } 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]; + // Store last value of row prior to reading + matrix_row_t last_row_value = current_matrix[current_row]; - // Clear data in matrix row - current_matrix[current_row] = 0; + // Clear data in matrix row + current_matrix[current_row] = 0; - // Select row and wait for row selection to stabilize - select_row(current_row); - wait_us(30); + // Select row and wait for row selection to stabilize + select_row(current_row); + // Skip the wait_us(30); as i2c is slow enough to debounce the io changes - current_matrix[current_row] = read_cols(); + current_matrix[current_row] = read_cols(); - // No need to Unselect row as the next `select_row` will blank everything + // No need to Unselect row as the next `select_row` will blank everything - return (last_row_value != current_matrix[current_row]); + return (last_row_value != current_matrix[current_row]); } //_____CUSTOM MATRIX IMPLEMENTATION____________________________________________________ void custom_matrix_init(void) { - pca9555_init(IC1); - pca9555_init(IC2); + pca9555_init(IC1); + pca9555_init(IC2); - init_pins(); + init_pins(); } bool custom_matrix_scan(matrix_row_t current_matrix[]) { - bool changed = false; - for (uint8_t current_row = 0; current_row < MATRIX_ROWS; current_row++) { - changed |= read_cols_on_row(current_matrix, current_row); - } - return changed; -} \ No newline at end of file + bool changed = false; + for (uint8_t current_row = 0; current_row < MATRIX_ROWS; current_row++) { + changed |= read_cols_on_row(current_matrix, current_row); + } + return changed; +}