Implemented input device.

This commit is contained in:
imi415 2021-06-30 02:28:58 +08:00
parent d2cd4cb29a
commit d2faa6c421
Signed by: imi415
GPG Key ID: 17F01E106F9F5E0A
13 changed files with 336 additions and 20 deletions

View File

@ -12,6 +12,7 @@ set(C_SOURCES
"src/drivers/user_config_driver.c"
"src/impl/user_st7789_impl.c"
"src/impl/user_lvgl_impl.c"
"src/impl/user_stick_impl.c"
"src/tasks/user_lvgl_task.c"
"src/tasks/user_clock_task.c"
"src/utils/user_log_util.c"

View File

@ -19,6 +19,9 @@ int user_gpio_init(user_gpio_t *gpio, char *chip, uint32_t offset,
uint8_t output_enabled);
int user_gpio_set(user_gpio_t *gpio, uint8_t value);
int user_gpio_get(user_gpio_t *gpio, uint8_t *value);
int user_gpio_intr_poll(user_gpio_t *gpio, uint32_t timeout_ms,
user_gpio_intr_t *event);
int user_gpio_setup_intr(user_gpio_t *gpio, user_gpio_intr_t type);
int user_gpio_deinit(user_gpio_t *gpio);
#endif

View File

@ -8,6 +8,10 @@ void user_lvgl_impl_init(void);
void user_lvgl_impl_flush_cb(lv_disp_drv_t *disp_drv, const lv_area_t *area,
lv_color_t *color_p);
void user_lvgl_impl_indev_read_cb(lv_indev_drv_t *drv, lv_indev_data_t *data);
void user_lvgl_impl_log_cb(const char *buf);
void *user_lvgl_impl_fs_open_cb(lv_fs_drv_t *drv, const char *path,
lv_fs_mode_t mode);

View File

@ -0,0 +1,34 @@
#ifndef USER_STICK_IMPL_H
#define USER_STICK_IMPL_H
#include "drivers/user_config_driver.h"
#include "drivers/user_gpio_driver.h"
#include "utils/user_log_util.h"
typedef enum {
USER_STICK_NONE,
USER_STICK_PUSH,
USER_STICK_UP,
USER_STICK_UPLEFT,
USER_STICK_UPRIGHT,
USER_STICK_DOWN,
USER_STICK_DOWNLEFT,
USER_STICK_DOWNRIGHT,
USER_STICK_LEFT,
USER_STICK_RIGHT,
} user_stick_key_t;
typedef struct {
user_gpio_t *push_gpio;
user_gpio_t *up_gpio;
user_gpio_t *down_gpio;
user_gpio_t *left_gpio;
user_gpio_t *right_gpio;
} user_stick_impl_t;
int user_stick_impl_init(user_stick_impl_t *stick);
user_stick_key_t user_stick_impl_read(user_stick_impl_t *stick);
int user_stick_impl_deinit(user_stick_impl_t *stick);
#endif

View File

@ -137,7 +137,7 @@ e.g. "stm32f769xx.h" or "stm32f429xx.h"*/
*-----------*/
/*Enable the log module*/
#define LV_USE_LOG 0
#define LV_USE_LOG 1
#if LV_USE_LOG
/*How important log should be added:
@ -147,7 +147,7 @@ e.g. "stm32f769xx.h" or "stm32f429xx.h"*/
*LV_LOG_LEVEL_ERROR Only critical issue, when the system may fail
*LV_LOG_LEVEL_USER Only logs added by the user
*LV_LOG_LEVEL_NONE Do not log anything*/
# define LV_LOG_LEVEL LV_LOG_LEVEL_WARN
# define LV_LOG_LEVEL LV_LOG_LEVEL_INFO
/*1: Print the log with 'printf';
*0: User need to register a callback with `lv_log_register_print_cb()`*/

View File

@ -30,6 +30,28 @@ agent: {
line = 231;
};
};
stick: {
up: {
path = "/dev/gpiochip2";
line = 232;
};
down: {
path = "/dev/gpiochip2";
line = 233;
};
left: {
path = "/dev/gpiochip2";
line = 234;
};
right: {
path = "/dev/gpiochip2";
line = 235;
};
push: {
path = "/dev/gpiochip2";
line = 236;
};
};
};
libraries: {

View File

@ -30,6 +30,28 @@ agent: {
line = 68;
};
};
stick: {
up: {
path = "/dev/gpiochip2";
line = 1;
};
down: {
path = "/dev/gpiochip2";
line = 3;
};
left: {
path = "/dev/gpiochip2";
line = 2;
};
right: {
path = "/dev/gpiochip2";
line = 4;
};
push: {
path = "/dev/gpiochip2";
line = 0;
};
};
};
libraries: {

View File

@ -30,6 +30,28 @@ agent: {
line = 12;
};
};
stick: {
up: {
path = "/dev/gpiochip2";
line = 1;
};
down: {
path = "/dev/gpiochip2";
line = 3;
};
left: {
path = "/dev/gpiochip2";
line = 2;
};
right: {
path = "/dev/gpiochip2";
line = 4;
};
push: {
path = "/dev/gpiochip2";
line = 0;
};
};
};
libraries: {

View File

@ -25,7 +25,7 @@ int user_gpio_init(user_gpio_t *gpio, char *chip, uint32_t offset,
if(output_enabled) {
ret = gpiod_line_request_output(gpio->line, CONSUMER_NAME, 1);
} else {
gpiod_line_request_input(gpio->line, CONSUMER_NAME);
ret = gpiod_line_request_input(gpio->line, CONSUMER_NAME);
}
if(ret != 0) {
@ -57,11 +57,10 @@ int user_gpio_setup_intr(user_gpio_t *gpio, user_gpio_intr_t type) {
else if(type == USER_GPIO_INTR_RISING | USER_GPIO_INTR_FALLING)
request_type = GPIOD_LINE_REQUEST_EVENT_BOTH_EDGES;
const struct gpiod_line_request_config config =
{
.consumer = CONSUMER_NAME,
.request_type = request_type,
};
const struct gpiod_line_request_config config = {
.consumer = CONSUMER_NAME,
.request_type = request_type,
};
int ret = gpiod_line_request(gpio->line, &config, 0);
if(ret != 0) {
@ -71,14 +70,28 @@ int user_gpio_setup_intr(user_gpio_t *gpio, user_gpio_intr_t type) {
return ret;
}
int user_gpio_intr_poll(user_gpio_t *gpio, uint32_t timeout_ms) {
int user_gpio_intr_poll(user_gpio_t *gpio, uint32_t timeout_ms,
user_gpio_intr_t *event) {
struct timespec ts = {
.tv_sec = timeout_ms / 1000,
.tv_nsec = (timeout_ms % 1000) * 1000000000
.tv_nsec = (timeout_ms % 1000) * 1000000000,
};
int ret = gpiod_line_event_wait(gpio->line, &ts);
struct gpiod_line_event ev;
return ret;
int ret = gpiod_line_event_wait(gpio->line, &ts);
if(ret > 0) {
ret = gpiod_line_event_read(gpio->line, &ev);
}
if(ret < 0) return ret;
if(ev.event_type == GPIOD_LINE_EVENT_RISING_EDGE) {
*event = USER_GPIO_INTR_RISING;
} else {
*event = USER_GPIO_INTR_FALLING;
}
return 0;
}
int user_gpio_get(user_gpio_t *gpio, uint8_t *value) {

View File

@ -6,12 +6,14 @@
#include "impl/user_lvgl_impl.h"
#include "impl/user_st7789_impl.h"
#include "impl/user_stick_impl.h"
#include "utils/user_log_util.h"
extern user_config_t g_config;
user_st7789_impl_t g_lcd_impl;
user_stick_impl_t g_stick_impl;
st7789_lcd_t g_lcd = {
.cb =
{
@ -30,8 +32,11 @@ st7789_lcd_t g_lcd = {
.user_data = &g_lcd_impl,
};
static user_stick_key_t s_previous_key = USER_STICK_NONE;
void user_lvgl_impl_init(void) {
user_st7789_impl_init(&g_lcd_impl);
user_stick_impl_init(&g_stick_impl);
st7789_lcd_init(&g_lcd);
}
@ -42,8 +47,44 @@ void user_lvgl_impl_flush_cb(lv_disp_drv_t *disp_drv, const lv_area_t *area,
lv_disp_flush_ready(disp_drv);
}
bool user_lvgl_indev_read_cb(lv_indev_drv_t *drv, lv_indev_data_t *data) {
//
void user_lvgl_impl_indev_read_cb(lv_indev_drv_t *drv, lv_indev_data_t *data) {
user_stick_key_t key = user_stick_impl_read(&g_stick_impl);
user_stick_key_t key_to_determine = USER_STICK_NONE;
if(key != s_previous_key) { // Key state changed
if(s_previous_key == USER_STICK_NONE) { // New key pressed
data->state = LV_INDEV_STATE_PR;
key_to_determine = key;
} else {
data->state = LV_INDEV_STATE_REL;
key_to_determine = s_previous_key;
}
switch(key_to_determine) {
case USER_STICK_LEFT:
data->key = LV_KEY_LEFT;
break;
case USER_STICK_RIGHT:
data->key = LV_KEY_RIGHT;
break;
case USER_STICK_UP:
data->key = LV_KEY_UP;
break;
case USER_STICK_DOWN:
data->key = LV_KEY_DOWN;
break;
case USER_STICK_PUSH:
data->key = LV_KEY_ENTER;
break;
default:
data->state = LV_INDEV_STATE_REL;
break;
}
s_previous_key = key;
USER_LOG(USER_LOG_INFO, "Stick event: %d, key: %d", data->state, data->key);
}
}
void user_lvgl_impl_log_cb(const char *buf) {
USER_LOG(USER_LOG_DEBUG, "LVGL: %s", buf);
}
void *user_lvgl_impl_fs_open_cb(lv_fs_drv_t *drv, const char *path,

View File

@ -9,7 +9,7 @@
extern user_config_t g_config;
int _user_st7789_impl_init_pin(user_gpio_t *gpio, char *pin_name, uint8_t is_output) {
static int user_st7789_impl_init_pin(user_gpio_t *gpio, char *pin_name, uint8_t is_output) {
char *chip;
uint32_t offset;
@ -62,24 +62,24 @@ int user_st7789_impl_init(void *handle) {
goto free_and_exit;
}
if(_user_st7789_impl_init_pin(impl->dc_gpio, "dc", 1) != 0) {
if(user_st7789_impl_init_pin(impl->dc_gpio, "dc", 1) != 0) {
USER_LOG(USER_LOG_ERROR, "DC pin not found, can not continue.");
goto deinit_spi_and_exit;
}
if(_user_st7789_impl_init_pin(impl->cs_gpio, "cs", 1) != 0) {
if(user_st7789_impl_init_pin(impl->cs_gpio, "cs", 1) != 0) {
free(impl->cs_gpio);
impl->cs_gpio = NULL;
USER_LOG(USER_LOG_WARN, "No CS pin found, SPI must be correctly configured.");
}
if(_user_st7789_impl_init_pin(impl->reset_gpio, "reset", 1) != 0) {
if(user_st7789_impl_init_pin(impl->reset_gpio, "reset", 1) != 0) {
free(impl->reset_gpio);
impl->reset_gpio = NULL;
USER_LOG(USER_LOG_WARN, "No Reset pin found.");
}
if(_user_st7789_impl_init_pin(impl->bl_gpio, "backlight", 1) != 0) {
if(user_st7789_impl_init_pin(impl->bl_gpio, "backlight", 1) != 0) {
free(impl->bl_gpio);
impl->bl_gpio = NULL;
USER_LOG(USER_LOG_WARN, "No backlight pin found.");

145
src/impl/user_stick_impl.c Normal file
View File

@ -0,0 +1,145 @@
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include "impl/user_stick_impl.h"
extern user_config_t g_config;
static int user_stick_impl_init_pin(user_gpio_t *gpio, char *pin_name, uint8_t is_output) {
char *chip;
uint32_t offset;
USER_LOG(USER_LOG_DEBUG, "Init GPIO %s", pin_name);
char name_buffer[64];
snprintf(name_buffer, 64, "agent.devices.stick.%s.path", pin_name);
chip = user_config_lookup_string(&g_config, name_buffer);
if(chip == NULL) return -1;
snprintf(name_buffer, 64, "agent.devices.stick.%s.line", pin_name);
if(user_config_lookup_int(&g_config, name_buffer, &offset) != 0) return -2;
if(user_gpio_init(gpio, chip, offset, is_output) != 0) return -3;
return 0;
}
int user_stick_impl_init(user_stick_impl_t *stick) {
memset(stick, 0x00, sizeof(user_stick_impl_t));
stick->push_gpio = malloc(sizeof(user_gpio_t));
if(!stick->push_gpio) goto free_and_exit;
stick->up_gpio = malloc(sizeof(user_gpio_t));
if(!stick->up_gpio) goto free_and_exit;
stick->down_gpio = malloc(sizeof(user_gpio_t));
if(!stick->down_gpio) goto free_and_exit;
stick->left_gpio = malloc(sizeof(user_gpio_t));
if(!stick->left_gpio) goto free_and_exit;
stick->right_gpio = malloc(sizeof(user_gpio_t));
if(!stick->right_gpio) goto free_and_exit;
if(user_stick_impl_init_pin(stick->push_gpio, "push", 0) != 0) {
free(stick->push_gpio);
stick->push_gpio = NULL;
goto deinit_and_exit;
}
if(user_stick_impl_init_pin(stick->up_gpio, "up", 0) != 0) {
free(stick->up_gpio);
stick->up_gpio = NULL;
goto deinit_and_exit;
}
if(user_stick_impl_init_pin(stick->down_gpio, "down", 0) != 0) {
free(stick->down_gpio);
stick->down_gpio = NULL;
goto deinit_and_exit;
}
if(user_stick_impl_init_pin(stick->left_gpio, "left", 0) != 0) {
free(stick->left_gpio);
stick->left_gpio = NULL;
goto deinit_and_exit;
}
if(user_stick_impl_init_pin(stick->right_gpio, "right", 0) != 0) {
free(stick->right_gpio);
stick->right_gpio = NULL;
goto deinit_and_exit;
}
USER_LOG(USER_LOG_INFO, "Stick initialized successfully.");
return 0;
deinit_and_exit:
USER_LOG(USER_LOG_ERROR, "Failed to initialize GPIO.");
if(stick->push_gpio) user_gpio_deinit(stick->push_gpio);
if(stick->up_gpio) user_gpio_deinit(stick->up_gpio);
if(stick->down_gpio) user_gpio_deinit(stick->down_gpio);
if(stick->left_gpio) user_gpio_deinit(stick->left_gpio);
if(stick->right_gpio) user_gpio_deinit(stick->right_gpio);
free_and_exit:
USER_LOG(USER_LOG_ERROR, "Failed to allocate memory.");
if(stick->push_gpio) free(stick->push_gpio);
if(stick->up_gpio) free(stick->up_gpio);
if(stick->down_gpio) free(stick->down_gpio);
if(stick->left_gpio) free(stick->left_gpio);
if(stick->right_gpio) free(stick->right_gpio);
return -1;
}
user_stick_key_t user_stick_impl_read(user_stick_impl_t *stick) {
uint8_t val[5];
user_gpio_get(stick->push_gpio, &val[0]);
user_gpio_get(stick->up_gpio, &val[1]);
user_gpio_get(stick->down_gpio, &val[2]);
user_gpio_get(stick->left_gpio, &val[3]);
user_gpio_get(stick->right_gpio, &val[4]);
if(val[0]) return USER_STICK_NONE;
else {
if(!(val[1] || val[3])) return USER_STICK_UPLEFT;
if(!(val[1] || val[4])) return USER_STICK_UPRIGHT;
if(!(val[2] || val[3])) return USER_STICK_DOWNLEFT;
if(!(val[2] || val[4])) return USER_STICK_DOWNRIGHT;
if(!val[1]) return USER_STICK_UP;
if(!val[2]) return USER_STICK_DOWN;
if(!val[3]) return USER_STICK_LEFT;
if(!val[4]) return USER_STICK_RIGHT;
}
return USER_STICK_PUSH;
}
int user_stick_impl_deinit(user_stick_impl_t *stick) {
if(stick->push_gpio) {
user_gpio_deinit(stick->push_gpio);
free(stick->push_gpio);
}
if(stick->up_gpio) {
user_gpio_deinit(stick->up_gpio);
free(stick->up_gpio);
}
if(stick->down_gpio) {
user_gpio_deinit(stick->down_gpio);
free(stick->down_gpio);
}
if(stick->left_gpio) {
user_gpio_deinit(stick->left_gpio);
free(stick->left_gpio);
}
if(stick->right_gpio) {
user_gpio_deinit(stick->right_gpio);
free(stick->right_gpio);
}
USER_LOG(USER_LOG_INFO, "Stick de-initialized successfully.");
return 0;
}

View File

@ -22,6 +22,7 @@ static lv_disp_draw_buf_t s_disp_buf;
static lv_color_t s_pix_buf[2][PIXBUF_SIZE];
static lv_disp_drv_t s_disp_drv;
static lv_fs_drv_t s_fs_drv;
static lv_indev_drv_t s_indev_drv;
void *user_lv_task(void *arguments);
void *user_lv_tick(void *arguments);
@ -35,9 +36,10 @@ int user_lvgl_task_init(void) {
lv_init();
lv_log_register_print_cb(user_lvgl_impl_log_cb);
lv_disp_draw_buf_init(&s_disp_buf, s_pix_buf[0], s_pix_buf[1], PIXBUF_SIZE);
lv_disp_drv_init(&s_disp_drv);
s_disp_drv.draw_buf = &s_disp_buf;
s_disp_drv.hor_res = 320;
@ -45,6 +47,13 @@ int user_lvgl_task_init(void) {
s_disp_drv.flush_cb = user_lvgl_impl_flush_cb;
lv_disp_t *disp = lv_disp_drv_register(&s_disp_drv);
lv_indev_drv_init(&s_indev_drv);
s_indev_drv.type = LV_INDEV_TYPE_KEYPAD;
s_indev_drv.read_cb = user_lvgl_impl_indev_read_cb;
lv_indev_t *indev = lv_indev_drv_register(&s_indev_drv);
lv_group_t *indev_group = lv_group_create();
lv_fs_drv_init(&s_fs_drv);
s_fs_drv.letter = 'A';
s_fs_drv.open_cb = user_lvgl_impl_fs_open_cb;