~ruther/qmk_firmware

1718dfa658dbe8ad144100b561794c5596ac5f08 — Joel Challis 5 years ago 1c8208a
Increase matrix scanning speed on xd84 (#7517)

* Increase matrix scanning speed

* Fix func name in failure output
3 files changed, 61 insertions(+), 38 deletions(-)

M drivers/gpio/pca9555.c
M drivers/gpio/pca9555.h
M keyboards/xd84/matrix.c
M drivers/gpio/pca9555.c => drivers/gpio/pca9555.c +17 -0
@@ 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;
}

M drivers/gpio/pca9555.h => drivers/gpio/pca9555.h +2 -0
@@ 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);

M keyboards/xd84/matrix.c => keyboards/xd84/matrix.c +42 -38
@@ 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;

  pca9555_set_output(IC1, PCA9555_PORT0, ALL_HIGH & (~mask));
  pca9555_set_config(IC1, PCA9555_PORT0, ALL_INPUT & (~mask));
    // 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;

    // 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);

  // 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);
    // 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);
    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;
}