From: https://github.com/zephyrproject-rtos/zephyr/issues/103807
Describe the bug
Hello,
I have configured a project based on the nRF5340 DK board and added adebounce-interval-ms property to the buttons. For this test, the debounce time is set to 5000 ms.
First interaction after reboot
- If I press the button briefly (< debounce time), the
pressedevent is not triggered, which is expected. - When I release the button, after
debounce_time_ms, thebutton releasedevent is triggered. Why?
From this point on, subsequent interactions behave as follows:
Subsequent interactions
- If I press the button briefly (< debounce time), the
pressedevent is not triggered (expected). - When I release the button, after
debounce_time_ms, thebutton releasedevent is not triggered, since the button never entered the pressed state. That's the expected behavior for me.
Is the initial behavior after a reboot expected? Or is it a bug?
Regression
-
This is a regression.
Steps to reproduce
The Device Tree is configured so that the resulting DTS for the buttons is:
buttons: buttons {
compatible = "gpio-keys";
debounce-interval-ms = < 0x1388 >;
button0: button_0 {
gpios = < &gpio0 0x17 0x11 >;
label = "Push button 1";
zephyr,code = < 0xb >;
};
button1: button_1 {
gpios = < &gpio0 0x18 0x11 >;
label = "Push button 2";
zephyr,code = < 0x2 >;
};
button2: button_2 {
gpios = < &gpio0 0x8 0x11 >;
label = "Push button 3";
zephyr,code = < 0x3 >;
};
button3: button_3 {
gpios = < &gpio0 0x9 0x11 >;
label = "Push button 4";
zephyr,code = < 0x4 >;
};
};
Then, the code:
static const struct device *const buttons_dev = DEVICE_DT_GET(DT_NODELABEL(buttons));
BUILD_ASSERT(DT_NODE_HAS_STATUS(DT_NODELABEL(buttons), okay));
static void buttons_event_cb(struct input_event *evt);
INPUT_CALLBACK_DEFINE(buttons_dev, buttons_event_cb);
static void buttons_event_cb(struct input_event *evt)
{
if (evt->type == INPUT_EV_KEY) {
switch (evt->code) {
case BTN2_CODE:
if (evt->value == 0) {
// Released
k_work_reschedule_for_queue(&g_events_work_q, &btn2_released_work,
K_MSEC(100));
} else {
// Pressed
k_work_reschedule_for_queue(&g_events_work_q, &btn2_pressed_work,
K_MSEC(100));
}
break;
default:
// Do nothing
break;
}
}
}
static void btn2_pressed_work_handler(struct k_work *work)
{
ARG_UNUSED(work);
LOG_INF("Button 2 pressed");
}
static void btn2_released_work_handler(struct k_work *work)
{
ARG_UNUSED(work);
LOG_INF("Button 2 released");
}
Then:
- Reboot the device.
- Wait any amount of time (it does not matter if it is much longer than the debounce time).
- Quickly press and release the button (< debounce time).
- Observe that the button pressed event does not occur.
- After
debounce_time_msfrom releasing the button, the button released event is executed.
From this point on, if you repeat the same procedure:
- Quickly press and release the button (< debounce time).
- Observe that the button pressed event does not occur.
- After
debounce_time_msfrom releasing the button, the button released event is also not executed.
Relevant log output
<inf> main: Button 2 released
Impact
On startup, if there is a glitch during the Power On process, a Released Button event is ALWAYS triggered
Environment
OS: Kubuntu 24.04.3 LTS
nRF SDK Version: 2.6.4
Zephyr Version: 3.5.99-ncs1-4
Board: nRF5340 DK