Trying to implement longpress function for keypad, but don't know what to set in the device tree for input-device

I'm running V2.60 NCD on a custom n5340 processor and I can't decipher what is the proper device tree based on the examples.

I have a 10 button keypad and want to detect short and long presses on all the keys. 

i tried the test suite code here: v2.6.0\zephyr\tests\subsys\input\input_longpress  which runs (simulating keypresses) and I get the test_cb() to execute.  I can read the keypad via 

gpio_pin_get_dt() manually, so I know that is all connected ok.

 Here is the zephyr testsuite code and their devicetree

Fullscreen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
tatic const struct device *const fake_dev = DEVICE_DT_GET(
DT_NODELABEL(fake_input_device));
static const struct device *const longpress_dev = DEVICE_DT_GET(
DT_NODELABEL(longpress));
DEVICE_DT_DEFINE(DT_INST(0, vnd_input_device), NULL, NULL, NULL, NULL,
PRE_KERNEL_1, CONFIG_KERNEL_INIT_PRIORITY_DEVICE, NULL);
static int event_count;
static struct input_event last_events[2];
static void test_cb(struct input_event *evt)
{
TC_PRINT("%s: %d %x %d\n", __func__, event_count, evt->code, evt->value);
event_count++;
memcpy(&last_events[1], &last_events[0], sizeof(struct input_event));
memcpy(&last_events[0], evt, sizeof(struct input_event));
}
INPUT_CALLBACK_DEFINE(longpress_dev, test_cb);
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Their Device tree

Fullscreen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <zephyr/dt-bindings/input/input-event-codes.h>
/ {
fake_input_device: fake-device {
compatible = "vnd,input-device";
};
longpress: longpress {
input = <&fake_input_device>;
compatible = "zephyr,input-longpress";
input-codes = <INPUT_KEY_0>, <INPUT_KEY_1>;
short-codes = <INPUT_KEY_A>, <INPUT_KEY_B>;
long-codes = <INPUT_KEY_X>, <INPUT_KEY_Y>;
long-delay-ms = <100>;
};
};
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

I used that same code changing from the "fake" names to mine, but  but I get this error during build:

C:/ncs/v2.6.0/zephyr/include/zephyr/toolchain/gcc.h:87:36: error: static assertion failed: "zephyr-code must be specified to use the input-gpio-keys driver".

here's my devicetree file.  I don't know what to use for the kp_input_device compatible value (probably causing the error?).  The test code uses "vnd,input-device" which is a dummy device for test suite.

 my device tree

Fullscreen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
buttons: buttons {
compatible = "gpio-keys";
btntopleft: button_0 {
gpios = <&gpio0 23 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>;
label = "BTN_TOP_LEFT";
zephyr,code = <INPUT_KEY_0>;
};
btntopmid: button_1 {
gpios = <&gpio1 5 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>;
label = "BTN_TOP_MIDDLE";
zephyr,code = <INPUT_KEY_1>;
};
btntopright: button_2 {
gpios = <&gpio1 7 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>;
label = "BTN_TOP_RIGHT";
zephyr,code = <INPUT_KEY_2>;
};
btnleft: button_3 {
gpios = <&gpio1 9 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>;
label = "BTN_LEFT";
zephyr,code = <INPUT_KEY_3>;
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

my longpress code

Fullscreen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <zephyr/device.h>
#include <zephyr/input/input.h>
#include <zephyr/kernel.h>
//#include <zephyr/ztest.h>
LOG_MODULE_REGISTER(longpress, LOG_LEVEL_INF);
static const struct device *const kp_dev = DEVICE_DT_GET(
DT_NODELABEL(kp_input_device));
static const struct device *const longpress_dev = DEVICE_DT_GET(
DT_NODELABEL(longpress));
DEVICE_DT_DEFINE(DT_INST(0, vnd_input_device), NULL, NULL, NULL, NULL,
PRE_KERNEL_1, CONFIG_KERNEL_INIT_PRIORITY_DEVICE, NULL);
static int event_count;
static struct input_event last_events[2];
static void longpress_cb(struct input_event *evt)
{
printk("%s: %d %x %d\n", __func__, event_count, evt->code, evt->value);
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

there is a good example code here: \v2.6.0\zephyr\subsys\input that has all the processing inside, but this has the same problem as above.

thanks

Parents Reply Children
  • thanks Siguard.  That is working, but I was trying to use the longpress feature in the devicetree (using CONFIG_INPUT=y).  I thought that would be an easier way.  The other question using the longpress feature, if it would work to detect two buttons pressed together.  I'll stay with your solution unless I hear otherwise.

  •   You should pass a different phandle (buttons) to the longpress device to be as an input reference (input = <&buttons>). So your device tree will look like this:

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    buttons: buttons {
    compatible = "gpio-keys";
    btntopleft: button_0 {
    gpios = <&gpio0 23 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>;
    label = "BTN_TOP_LEFT";
    zephyr,code = <INPUT_KEY_0>;
    };
    btntopmid: button_1 {
    gpios = <&gpio1 5 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>;
    label = "BTN_TOP_MIDDLE";
    zephyr,code = <INPUT_KEY_1>;
    };
    btntopright: button_2 {
    gpios = <&gpio1 7 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>;
    label = "BTN_TOP_RIGHT";
    zephyr,code = <INPUT_KEY_2>;
    };
    btnleft: button_3 {
    gpios = <&gpio1 9 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>;
    label = "BTN_LEFT";
    zephyr,code = <INPUT_KEY_3>;
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    In your source code you don't need lines

    Fullscreen
    1
    2
    static const struct device *const kp_dev = DEVICE_DT_GET(
    DT_NODELABEL(kp_input_device));
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    and 

    Fullscreen
    1
    2
    DEVICE_DT_DEFINE(DT_INST(0, vnd_input_device), NULL, NULL, NULL, NULL,
    PRE_KERNEL_1, CONFIG_KERNEL_INIT_PRIORITY_DEVICE, NULL);
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    since your keypad device is actually buttons and they've already been instantiated by Zephyr.


    Thanks!