board/main/ui.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, &current_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, &current_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);
}