kscan: Limit maximum amount of key presses to 3

When using a keyboard without diodes in the key matrix, ghosting can
become a serious issue. Quite often three keys held at the same time are
needed to produce a ghosted fourth key press when using a row, col based
keyboard matrix. In these cases it makes sense to allow only three key
presses at the same time, ignoring all of them if a fourth is pressed.

The changes made here are a simple work-of-proof how this "limit the
amount of key presses" could be done.

Note: There's no configuration options or similar to change this
behavior right now.

Signed-off-by: Sophie Tyalie <dev@flowerpot.me>
This commit is contained in:
Sophie Tyalie 2022-11-11 15:23:30 +01:00
parent 768fc4a5e5
commit 412376e8a4

View file

@ -225,6 +225,8 @@ static int kscan_matrix_read(const struct device *dev) {
struct kscan_matrix_data *data = dev->data;
const struct kscan_matrix_config *config = dev->config;
int num_active = 0;
int stored_states[3] = {0};
// Scan the matrix.
for (int o = 0; o < config->outputs.len; o++) {
const struct gpio_dt_spec *out_gpio = &config->outputs.gpios[o];
@ -245,8 +247,19 @@ static int kscan_matrix_read(const struct device *dev) {
const int index = state_index_io(config, i, o);
const bool active = gpio_pin_get_dt(in_gpio);
debounce_update(&data->matrix_state[index], active, config->debounce_scan_period_ms,
&config->debounce_config);
if (active) {
if (num_active < sizeof(stored_states) / sizeof(stored_states[0])) {
stored_states[num_active] = index;
}
num_active++;
} else {
debounce_update(&data->matrix_state[index], active,
config->debounce_scan_period_ms,
&config->debounce_config);
}
}
err = gpio_pin_set_dt(out_gpio, 0);
@ -260,6 +273,14 @@ static int kscan_matrix_read(const struct device *dev) {
#endif
}
if (0 < num_active && num_active <= 3) {
for (int i = 0; i < num_active; i++) {
int index = stored_states[i];
debounce_update(&data->matrix_state[index], true, config->debounce_scan_period_ms,
&config->debounce_config);
}
}
// Process the new state.
bool continue_scan = false;