157 lines
4.9 KiB
C
157 lines
4.9 KiB
C
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#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);
|
|
}
|