Skip to content

Commit

Permalink
Add toggle mode to direct-wire kscan
Browse files Browse the repository at this point in the history
  • Loading branch information
kurtis-lew committed Mar 19, 2022
1 parent 58c7c0e commit 8bb9021
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 2 deletions.
50 changes: 48 additions & 2 deletions app/drivers/kscan/kscan_gpio_direct.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ union work_reference {
struct kscan_gpio_config {
uint8_t num_of_inputs;
uint8_t debounce_period;
bool toggle_mode;
struct kscan_gpio_item_config inputs[];
};

Expand Down Expand Up @@ -127,6 +128,35 @@ static int kscan_gpio_direct_disable(const struct device *dev) {
}

#endif /* defined(CONFIG_ZMK_KSCAN_DIRECT_POLLING) */
static gpio_flags_t kscan_gpio_get_pulls(const struct kscan_gpio_item_config *in_cfg) {
if (in_cfg->flags == GPIO_ACTIVE_LOW) {
return GPIO_PULL_UP;
}
if (in_cfg->flags == GPIO_ACTIVE_HIGH) {
return GPIO_PULL_DOWN;
}
LOG_ERR("Could not determine proper pull direction based on pin flags for pin %d", in_cfg->pin);
return 0;
}

static int kscan_gpio_set_pulls(const struct device *dev, const gpio_pin_t active_pin) {
const struct kscan_gpio_config *cfg = dev->config;
for (int i = 0; i < cfg->num_of_inputs; i++) {
const struct device *in_dev = kscan_gpio_input_devices(dev)[i];
const struct kscan_gpio_item_config *in_cfg = &kscan_gpio_input_configs(dev)[i];
gpio_flags_t combined_flags = in_cfg->flags;
if (in_cfg->pin != active_pin) {
combined_flags = combined_flags | kscan_gpio_get_pulls(in_cfg);
}
int err = gpio_pin_configure(in_dev, in_cfg->pin, GPIO_INPUT | combined_flags);
if (err) {
LOG_ERR("Unable to configure pulls on pin %d on %s", in_cfg->pin, in_cfg->label);
return err;
}
LOG_DBG("Configured pin %d with flags %d", in_cfg->pin, GPIO_INPUT | combined_flags);
}
return 0;
}

static int kscan_gpio_direct_configure(const struct device *dev, kscan_callback_t callback) {
struct kscan_gpio_data *data = dev->data;
Expand All @@ -148,12 +178,17 @@ static int kscan_gpio_read(const struct device *dev) {
WRITE_BIT(read_state, i, gpio_pin_get(in_dev, in_cfg->pin) > 0);
}
for (int i = 0; i < cfg->num_of_inputs; i++) {
const struct kscan_gpio_item_config *in_cfg = &kscan_gpio_input_configs(dev)[i];
bool prev_pressed = BIT(i) & data->pin_state;
bool pressed = (BIT(i) & read_state) != 0;
submit_follow_up_read = (submit_follow_up_read || pressed);
if (pressed != prev_pressed) {
LOG_DBG("Sending event at %d,%d state %s", 0, i, (pressed ? "on" : "off"));
WRITE_BIT(data->pin_state, i, pressed);
if (cfg->toggle_mode && pressed) {
LOG_DBG("Updating pulls with pin %d as active pin", in_cfg->pin);
kscan_gpio_set_pulls(dev, in_cfg->pin);
}
data->callback(dev, 0, i, pressed);
}
}
Expand Down Expand Up @@ -199,14 +234,24 @@ static const struct kscan_driver_api gpio_driver_api = {
const struct kscan_gpio_config *cfg = dev->config; \
int err; \
const struct device **input_devices = kscan_gpio_input_devices(dev); \
if (cfg->toggle_mode) { \
LOG_DBG("Toggle mode ENABLED on %s", dev->name); \
} \
for (int i = 0; i < cfg->num_of_inputs; i++) { \
const struct kscan_gpio_item_config *in_cfg = &kscan_gpio_input_configs(dev)[i]; \
input_devices[i] = device_get_binding(in_cfg->label); \
if (!input_devices[i]) { \
LOG_ERR("Unable to find input GPIO device"); \
return -EINVAL; \
} \
err = gpio_pin_configure(input_devices[i], in_cfg->pin, GPIO_INPUT | in_cfg->flags); \
if (cfg->toggle_mode) { \
err = \
gpio_pin_configure(input_devices[i], in_cfg->pin, \
GPIO_INPUT | in_cfg->flags | kscan_gpio_get_pulls(in_cfg)); \
} else { \
err = \
gpio_pin_configure(input_devices[i], in_cfg->pin, GPIO_INPUT | in_cfg->flags); \
} \
if (err) { \
LOG_ERR("Unable to configure pin %d on %s for input", in_cfg->pin, in_cfg->label); \
return err; \
Expand Down Expand Up @@ -237,7 +282,8 @@ static const struct kscan_driver_api gpio_driver_api = {
static const struct kscan_gpio_config kscan_gpio_config_##n = { \
.inputs = {UTIL_LISTIFY(INST_INPUT_LEN(n), KSCAN_DIRECT_INPUT_ITEM, n)}, \
.num_of_inputs = INST_INPUT_LEN(n), \
.debounce_period = DT_INST_PROP(n, debounce_period)}; \
.debounce_period = DT_INST_PROP(n, debounce_period), \
.toggle_mode = DT_INST_PROP(n, toggle_mode)}; \
DEVICE_DT_INST_DEFINE(n, kscan_gpio_init_##n, device_pm_control_nop, &kscan_gpio_data_##n, \
&kscan_gpio_config_##n, POST_KERNEL, CONFIG_ZMK_KSCAN_INIT_PRIORITY, \
&gpio_driver_api);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ properties:
input-gpios:
type: phandle-array
required: true
toggle-mode:
type: boolean
debounce-period:
type: int
default: 5

0 comments on commit 8bb9021

Please sign in to comment.