#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); }