feat(kscan): Add toggle-mode to updated direct-wire kscan

This commit is contained in:
Kurtis Lew 2022-05-15 10:42:38 -07:00 committed by Pete Johanson
parent 90f3107c49
commit f369f2cc46
2 changed files with 42 additions and 0 deletions

View file

@ -76,6 +76,7 @@ struct kscan_direct_config {
struct debounce_config debounce_config; struct debounce_config debounce_config;
int32_t debounce_scan_period_ms; int32_t debounce_scan_period_ms;
int32_t poll_period_ms; int32_t poll_period_ms;
bool toggle_mode;
}; };
#if USE_INTERRUPTS #if USE_INTERRUPTS
@ -124,6 +125,40 @@ static void kscan_direct_irq_callback_handler(const struct device *port, struct
} }
#endif #endif
static gpio_flags_t kscan_gpio_get_flags(const struct gpio_dt_spec *gpio, bool active) {
if (((BIT(0) & gpio->dt_flags) == BIT(0))) { // Devicetree configured input ACTIVE_LOW
if (!active) {
return GPIO_ACTIVE_LOW | GPIO_PULL_UP;
}
return GPIO_ACTIVE_LOW;
} else { // Devicetree configured input ACTIVE_HIGH
if (!active) {
return GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN;
}
return GPIO_ACTIVE_HIGH;
}
LOG_ERR("Could not determine proper flags to set for pin %d", gpio->pin);
return 0;
}
static int kscan_inputs_set_flags(const struct kscan_gpio_list *inputs,
const struct gpio_dt_spec *active_gpio) {
gpio_flags_t updated_flags;
for (int i = 0; i < inputs->len; i++) {
updated_flags =
GPIO_INPUT | kscan_gpio_get_flags(&inputs->gpios[i], &inputs->gpios[i] == active_gpio);
LOG_DBG("Updated flags equal to: %d", updated_flags);
int err = gpio_pin_configure(inputs->gpios[i].port, inputs->gpios[i].pin, updated_flags);
if (err) {
LOG_ERR("Unable to configure flags on pin %d on %s", inputs->gpios[i].pin,
inputs->gpios[i].port->name);
return err;
}
}
return 0;
}
static void kscan_direct_read_continue(const struct device *dev) { static void kscan_direct_read_continue(const struct device *dev) {
const struct kscan_direct_config *config = dev->config; const struct kscan_direct_config *config = dev->config;
struct kscan_direct_data *data = dev->data; struct kscan_direct_data *data = dev->data;
@ -173,6 +208,9 @@ static int kscan_direct_read(const struct device *dev) {
LOG_DBG("Sending event at 0,%i state %s", i, pressed ? "on" : "off"); LOG_DBG("Sending event at 0,%i state %s", i, pressed ? "on" : "off");
data->callback(dev, 0, i, pressed); data->callback(dev, 0, i, pressed);
if (config->toggle_mode && pressed) {
kscan_inputs_set_flags(&config->inputs, &config->inputs.gpios[i]);
}
} }
continue_scan = continue_scan || debounce_is_active(state); continue_scan = continue_scan || debounce_is_active(state);
@ -317,6 +355,7 @@ static const struct kscan_driver_api kscan_direct_api = {
}, \ }, \
.debounce_scan_period_ms = DT_INST_PROP(n, debounce_scan_period_ms), \ .debounce_scan_period_ms = DT_INST_PROP(n, debounce_scan_period_ms), \
.poll_period_ms = DT_INST_PROP(n, poll_period_ms), \ .poll_period_ms = DT_INST_PROP(n, poll_period_ms), \
.toggle_mode = DT_INST_PROP(n, toggle_mode), \
}; \ }; \
\ \
DEVICE_DT_INST_DEFINE(n, &kscan_direct_init, NULL, &kscan_direct_data_##n, \ DEVICE_DT_INST_DEFINE(n, &kscan_direct_init, NULL, &kscan_direct_data_##n, \

View file

@ -32,3 +32,6 @@ properties:
type: int type: int
default: 10 default: 10
description: Time between reads in milliseconds when no key is pressed and ZMK_KSCAN_DIRECT_POLLING is enabled. description: Time between reads in milliseconds when no key is pressed and ZMK_KSCAN_DIRECT_POLLING is enabled.
toggle-mode:
type: boolean
description: Enable toggle-switch mode.