From 02dfa1385e25875659eec20313b8914ccbf60954 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ma=C3=ABl=20Gassmann?= Date: Fri, 11 Oct 2024 02:18:54 +0200 Subject: [+] Button module with long / short press and release detection --- components/button/button_handler.c | 76 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 components/button/button_handler.c (limited to 'components/button/button_handler.c') diff --git a/components/button/button_handler.c b/components/button/button_handler.c new file mode 100644 index 0000000..eb89212 --- /dev/null +++ b/components/button/button_handler.c @@ -0,0 +1,76 @@ +#include "button_handler.h" + +bool is_pressed(struct Button* b) +{ + return b->time > b->p_time; +} + +bool was_pressed(struct Button* b, int64_t since) +{ + return b->time >= b->p_time && b->time > since; +} + +bool was_pressed_and_released(struct Button* b, int64_t since) +{ + return b->time == b->p_time && b->time > since; +} + +bool was_short_pressed(struct Button* b, int64_t since) +{ + return (is_pressed(b) && (esp_timer_get_time() - b->time)/1000 < LONG_PRESS) || (was_pressed_and_released(b, since) && b->dt < LONG_PRESS); +} + +bool was_long_pressed(struct Button* b, int64_t since) +{ + return (is_pressed(b) && (esp_timer_get_time() - b->time)/1000 >= LONG_PRESS) || (was_pressed_and_released(b, since) && b->dt >= LONG_PRESS); +} + +bool was_short_pressed_and_released(struct Button* b, int64_t since) +{ + return was_pressed_and_released(b, since) && b->dt < LONG_PRESS; +} + +bool was_long_pressed_and_released(struct Button* b, int64_t since) +{ + return was_pressed_and_released(b, since) && b->dt >= LONG_PRESS; +} + +static void IRAM_ATTR button_handler(void* arg) { + struct Button* b = (struct Button*)arg; + xQueueSendFromISR(uinput_evt_queue, &b, NULL); +} + +void button_task(void* arg) { + struct Button* b; + while (1) { + if (xQueueReceive(uinput_evt_queue, &b, portMAX_DELAY)) { + uint8_t lvl = gpio_get_level(b->pin); + if (lvl == 0 && (b->time == b->p_time || b->time == 0)) { // Button pressed + b->time = esp_timer_get_time(); + printf("Button pressed\n"); + } else if (lvl == 1 && b->time != b->p_time) { // Button released + b->dt = (esp_timer_get_time() - b->time) / 1000; + printf("Button released after %d ms\n", b->dt); + b->p_time = b->time; + } + } + } +} + + +void setup_button(struct Button* b) { + b->pin = CONFIG_BUTTON_PIN; // Assume CONFIG_BUTTON_PIN is defined + + gpio_config_t io_conf = { + .intr_type = GPIO_INTR_ANYEDGE, + .pin_bit_mask = (1ULL << b->pin), + .mode = GPIO_MODE_INPUT, + .pull_up_en = GPIO_PULLUP_ENABLE, + }; + gpio_config(&io_conf); + + uinput_evt_queue = xQueueCreate(10, sizeof(struct Button*)); + xTaskCreate(button_task, "button_task", 2048, NULL, 10, NULL); + gpio_install_isr_service(ESP_INTR_FLAG_DEFAULT); + gpio_isr_handler_add(b->pin, button_handler, (void*)b); +} \ No newline at end of file -- cgit v1.2.3