#include #include #include #include "driver/gpio.h" #include "freertos/FreeRTOS.h" #include "freertos/queue.h" #include "freertos/task.h" #define GPIO_OUTPUT_IO_0 5 #define GPIO_OUTPUT_IO_1 6 #define GPIO_OUTPUT_PIN_SEL \ ((1ULL << GPIO_OUTPUT_IO_0) | (1ULL << GPIO_OUTPUT_IO_1)) #define ENCODER_0_CLK_PIN CONFIG_ENCODER_0_CLK_PIN #define ENCODER_0_DT_PIN CONFIG_ENCODER_0_DT_PIN #define ENCODER_0_CLK_PIN_MASK 1ULL << ENCODER_0_CLK_PIN #define ENCODER_0_DT_PIN_MASK 1ULL << ENCODER_0_DT_PIN #define ENCODER_1_CLK_PIN CONFIG_ENCODER_1_CLK_PIN #define ENCODER_1_DT_PIN CONFIG_ENCODER_1_DT_PIN #define ENCODER_1_CLK_PIN_MASK 1ULL << ENCODER_1_CLK_PIN #define ENCODER_1_DT_PIN_MASK 1ULL << ENCODER_1_DT_PIN #define ESP_INTR_FLAG_DEFAULT 0 #define NOT_ROTATING -1 #define CLOCKWISE 1 #define COUNTER_CLOCKWISE 0 #define UI_INPUT_DISPLAY_0_BRIGHTNESS 1 #define UI_INPUT_DISPLAY_1_BRIGHTNESS 2 typedef struct s_ui_input { uint8_t key; uint16_t value; } s_ui_input_t; static xQueueHandle ui_input_event = NULL; static int8_t rising_edge_rotation_direction = NOT_ROTATING; static int8_t falling_edge_rotation_direction = NOT_ROTATING; static uint8_t display_0_brightness = 20; static uint8_t display_1_brightness = 20; static s_ui_input_t current_ui_input = {}; uint8_t input_key; uint8_t clk_pin = ENCODER_0_CLK_PIN; uint8_t dt_level; uint8_t dt_pin = ENCODER_0_DT_PIN; uint8_t* value = &display_0_brightness; static void IRAM_ATTR gpio_isr_handler(void* arg) { uint8_t input_key = (uint8_t)arg; switch (input_key) { case UI_INPUT_DISPLAY_0_BRIGHTNESS: clk_pin = ENCODER_0_CLK_PIN; dt_pin = ENCODER_0_DT_PIN; value = &display_0_brightness; break; case UI_INPUT_DISPLAY_1_BRIGHTNESS: clk_pin = ENCODER_1_CLK_PIN; dt_pin = ENCODER_1_DT_PIN; value = &display_1_brightness; break; default: break; } dt_level = gpio_get_level(dt_pin); if (gpio_get_level(clk_pin)) { rising_edge_rotation_direction = dt_level == 0; if (falling_edge_rotation_direction == rising_edge_rotation_direction) { if (rising_edge_rotation_direction) { gpio_set_level(GPIO_OUTPUT_IO_0, 1); gpio_set_level(GPIO_OUTPUT_IO_1, 0); *value += 1; } else { gpio_set_level(GPIO_OUTPUT_IO_0, 0); gpio_set_level(GPIO_OUTPUT_IO_1, 1); *value -= 1; } falling_edge_rotation_direction = NOT_ROTATING; current_ui_input.key = input_key; current_ui_input.value = *value; xQueueSendFromISR(ui_input_event, ¤t_ui_input, NULL); } else { if (falling_edge_rotation_direction != NOT_ROTATING) { rising_edge_rotation_direction = NOT_ROTATING; } } } else { falling_edge_rotation_direction = dt_level; // printf("F %d\t", falling_edge_rotation_direction); if (rising_edge_rotation_direction == falling_edge_rotation_direction) { if (falling_edge_rotation_direction) { gpio_set_level(GPIO_OUTPUT_IO_0, 1); gpio_set_level(GPIO_OUTPUT_IO_1, 0); *value += 1; } else { gpio_set_level(GPIO_OUTPUT_IO_0, 0); gpio_set_level(GPIO_OUTPUT_IO_1, 1); *value -= 1; } rising_edge_rotation_direction = NOT_ROTATING; current_ui_input.key = input_key; current_ui_input.value = *value; xQueueSendFromISR(ui_input_event, ¤t_ui_input, NULL); } else { if (rising_edge_rotation_direction != NOT_ROTATING) { falling_edge_rotation_direction = NOT_ROTATING; } } } } void init_ui(void) { // zero-initialize the config structure. gpio_config_t io_conf = {}; // disable interrupt io_conf.intr_type = GPIO_INTR_DISABLE; // set as output mode io_conf.mode = GPIO_MODE_OUTPUT; // bit mask of the pins that you want to set,e.g.GPIO18/19 io_conf.pin_bit_mask = GPIO_OUTPUT_PIN_SEL; // disable pull-down mode io_conf.pull_down_en = 0; // disable pull-up mode io_conf.pull_up_en = 0; // configure GPIO with the given settings gpio_config(&io_conf); io_conf.mode = GPIO_MODE_INPUT; io_conf.pull_up_en = 1; io_conf.pull_down_en = 0; // interrupt of rising edge io_conf.intr_type = GPIO_INTR_ANYEDGE; io_conf.pin_bit_mask = ENCODER_0_CLK_PIN_MASK | ENCODER_1_CLK_PIN_MASK; gpio_config(&io_conf); io_conf.intr_type = GPIO_INTR_DISABLE; io_conf.pin_bit_mask = ENCODER_0_DT_PIN_MASK | ENCODER_1_DT_PIN_MASK; gpio_config(&io_conf); // start encoder task ui_input_event = xQueueCreate(10, sizeof(s_ui_input_t)); // install gpio isr service gpio_install_isr_service(ESP_INTR_FLAG_DEFAULT); // hook isr handler for specific gpio pin gpio_isr_handler_add(ENCODER_0_CLK_PIN, gpio_isr_handler, (void*)UI_INPUT_DISPLAY_0_BRIGHTNESS); // hook isr handler for specific gpio pin gpio_isr_handler_add(ENCODER_1_CLK_PIN, gpio_isr_handler, (void*)UI_INPUT_DISPLAY_1_BRIGHTNESS); }