input_gpio_keys: First 'debounce-interval-ms' not applied properly for button release

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 a
debounce-interval-ms property to the buttons. For this test, the debounce time is set to 5000 ms.

First interaction after reboot

  1. If I press the button briefly (< debounce time), the pressed event is not triggered, which is expected.
  2. When I release the button, after debounce_time_ms, the button released event is triggered. Why?

From this point on, subsequent interactions behave as follows:

Subsequent interactions

  1. If I press the button briefly (< debounce time), the pressed event is not triggered (expected).
  2. When I release the button, after debounce_time_ms, the button released event 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:

  1. Reboot the device.
  2. Wait any amount of time (it does not matter if it is much longer than the debounce time).
  3. Quickly press and release the button (< debounce time).
  4. Observe that the button pressed event does not occur.
  5. After debounce_time_ms from releasing the button, the button released event is executed.

From this point on, if you repeat the same procedure:

  1. Quickly press and release the button (< debounce time).
  2. Observe that the button pressed event does not occur.
  3. After debounce_time_ms from 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

Parents Reply Children
No Data
Related