feat(nuttx): add libuv mode for nuttx dev and poll for nuttx fbdev (#4683)
Signed-off-by: YanXiaowei <yanxiaowei@xiaomi.com> Signed-off-by: rongyichang <rongyichang@xiaomi.com> Co-authored-by: YanXiaowei <yanxiaowei@xiaomi.com>
This commit is contained in:
5
Kconfig
5
Kconfig
@@ -1269,6 +1269,11 @@ menu "LVGL configuration"
|
||||
bool "Use Nuttx to open window and handle touchscreen"
|
||||
default n
|
||||
|
||||
config LV_USE_NUTTX_LIBUV
|
||||
bool "Use uv loop to replace default timer loop and other fb/indev timers"
|
||||
depends on LV_USE_NUTTX
|
||||
default n
|
||||
|
||||
config LV_USE_NUTTX_CUSTOM_INIT
|
||||
bool "Use Custom Nuttx init API to open window and handle touchscreen"
|
||||
depends on LV_USE_NUTTX
|
||||
|
||||
@@ -763,19 +763,24 @@
|
||||
/*Use Nuttx to open window and handle touchscreen*/
|
||||
#define LV_USE_NUTTX 0
|
||||
|
||||
/*Use Nuttx custom init API to open window and handle touchscreen*/
|
||||
#define LV_USE_NUTTX_CUSTOM_INIT 0
|
||||
#if LV_USE_NUTTX
|
||||
#define LV_USE_NUTTX_LIBUV 0
|
||||
|
||||
/*Use Nuttx custom init API to open window and handle touchscreen*/
|
||||
#define LV_USE_NUTTX_CUSTOM_INIT 0
|
||||
|
||||
/*Driver for /dev/lcd*/
|
||||
#define LV_USE_NUTTX_LCD 0
|
||||
#if LV_USE_NUTTX_LCD
|
||||
#define LV_NUTTX_LCD_BUFFER_COUNT 0
|
||||
#define LV_NUTTX_LCD_BUFFER_SIZE 60
|
||||
#endif
|
||||
|
||||
/*Driver for /dev/input*/
|
||||
#define LV_USE_NUTTX_TOUCHSCREEN 0
|
||||
|
||||
/*Driver for /dev/lcd*/
|
||||
#define LV_USE_NUTTX_LCD 0
|
||||
#if LV_USE_NUTTX_LCD
|
||||
#define LV_NUTTX_LCD_BUFFER_COUNT 0
|
||||
#define LV_NUTTX_LCD_BUFFER_SIZE 60
|
||||
#endif
|
||||
|
||||
/*Driver for /dev/input*/
|
||||
#define LV_USE_NUTTX_TOUCHSCREEN 0
|
||||
|
||||
/*Driver for /dev/dri/card*/
|
||||
#define LV_USE_LINUX_DRM 0
|
||||
|
||||
|
||||
1
lvgl.h
1
lvgl.h
@@ -122,6 +122,7 @@ extern "C" {
|
||||
#include "src/dev/nuttx/lv_nuttx_fbdev.h"
|
||||
#include "src/dev/nuttx/lv_nuttx_touchscreen.h"
|
||||
#include "src/dev/nuttx/lv_nuttx_lcd.h"
|
||||
#include "src/dev/nuttx/lv_nuttx_libuv.h"
|
||||
|
||||
#include "src/dev/evdev/lv_evdev.h"
|
||||
|
||||
|
||||
@@ -13,7 +13,8 @@
|
||||
#include <time.h>
|
||||
#include <nuttx/tls.h>
|
||||
#include <syslog.h>
|
||||
#include <lvgl/lvgl.h>
|
||||
|
||||
#include "../../../lvgl.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
@@ -44,10 +45,6 @@ static void syslog_print(lv_log_level_t level, const char * buf);
|
||||
|
||||
#if LV_ENABLE_GLOBAL_CUSTOM
|
||||
|
||||
/****************************************************************************
|
||||
* Name: lv_global_free
|
||||
****************************************************************************/
|
||||
|
||||
static void lv_global_free(void * data)
|
||||
{
|
||||
if(data) {
|
||||
@@ -55,10 +52,6 @@ static void lv_global_free(void * data)
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: lv_global_default
|
||||
****************************************************************************/
|
||||
|
||||
lv_global_t * lv_global_default(void)
|
||||
{
|
||||
static int index = -1;
|
||||
@@ -79,46 +72,50 @@ lv_global_t * lv_global_default(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
void lv_nuttx_info_init(lv_nuttx_t * info)
|
||||
void lv_nuttx_dsc_init(lv_nuttx_dsc_t * dsc)
|
||||
{
|
||||
lv_memzero(info, sizeof(lv_nuttx_t));
|
||||
info->fb_path = "/dev/fb0";
|
||||
info->input_path = "/dev/input0";
|
||||
lv_memzero(dsc, sizeof(lv_nuttx_dsc_t));
|
||||
dsc->fb_path = "/dev/fb0";
|
||||
dsc->input_path = "/dev/input0";
|
||||
}
|
||||
|
||||
lv_display_t * lv_nuttx_init(const lv_nuttx_t * info)
|
||||
void lv_nuttx_init(const lv_nuttx_dsc_t * dsc, lv_nuttx_result_t * result)
|
||||
{
|
||||
lv_display_t * disp = NULL;
|
||||
|
||||
lv_log_register_print_cb(syslog_print);
|
||||
lv_tick_set_cb(millis);
|
||||
|
||||
#if !LV_USE_NUTTX_CUSTOM_INIT
|
||||
|
||||
if(info && info->fb_path) {
|
||||
if(dsc && dsc->fb_path) {
|
||||
lv_display_t * disp = NULL;
|
||||
|
||||
#if LV_USE_NUTTX_LCD
|
||||
disp = lv_nuttx_lcd_create(info->fb_path);
|
||||
disp = lv_nuttx_lcd_create(dsc->fb_path);
|
||||
#else
|
||||
disp = lv_nuttx_fbdev_create();
|
||||
if(lv_nuttx_fbdev_set_file(disp, info->fb_path) != 0) {
|
||||
if(lv_nuttx_fbdev_set_file(disp, dsc->fb_path) != 0) {
|
||||
lv_display_remove(disp);
|
||||
disp = NULL;
|
||||
}
|
||||
#endif
|
||||
if(result) {
|
||||
result->disp = disp;
|
||||
}
|
||||
}
|
||||
|
||||
if(info && info->input_path) {
|
||||
if(dsc && dsc->input_path) {
|
||||
#if LV_USE_NUTTX_TOUCHSCREEN
|
||||
lv_nuttx_touchscreen_create(info->input_path);
|
||||
lv_indev_t * indev = lv_nuttx_touchscreen_create(dsc->input_path);
|
||||
if(result) {
|
||||
result->indev = indev;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
disp = lv_nuttx_init_custom(info);
|
||||
lv_nuttx_init_custom(dsc, result);
|
||||
#endif
|
||||
|
||||
return disp;
|
||||
}
|
||||
|
||||
/**********************
|
||||
|
||||
@@ -33,33 +33,37 @@ extern "C" {
|
||||
typedef struct {
|
||||
const char * fb_path;
|
||||
const char * input_path;
|
||||
bool need_wait_vsync;
|
||||
} lv_nuttx_t;
|
||||
} lv_nuttx_dsc_t;
|
||||
|
||||
typedef struct {
|
||||
lv_display_t * disp;
|
||||
lv_indev_t * indev;
|
||||
} lv_nuttx_result_t;
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Initialize the lv_nuttx_t structure with default values for the NuttX port of LVGL.
|
||||
* @param info Pointer to the lv_nuttx_t structure to be initialized.
|
||||
* Initialize the lv_nuttx_dsc_t structure with default values for the NuttX port of LVGL.
|
||||
* @param dsc Pointer to the lv_nuttx_dsc_t structure to be initialized.
|
||||
*/
|
||||
void lv_nuttx_info_init(lv_nuttx_t * info);
|
||||
void lv_nuttx_dsc_init(lv_nuttx_dsc_t * dsc);
|
||||
|
||||
/**
|
||||
* Initialize the LVGL display driver for NuttX using the provided configuration information.
|
||||
* @param info Pointer to the lv_nuttx_t structure containing the configuration information for the display driver.
|
||||
* @return Pointer to the lv_display_t structure representing the initialized display driver.
|
||||
* @param dsc Pointer to the lv_nuttx_dsc_t structure containing the configuration information for the display driver.
|
||||
* @param result Pointer to the lv_nuttx_result_t structure containing display and input device handler.
|
||||
*/
|
||||
lv_display_t * lv_nuttx_init(const lv_nuttx_t * info);
|
||||
void lv_nuttx_init(const lv_nuttx_dsc_t * dsc, lv_nuttx_result_t * result);
|
||||
|
||||
#if LV_USE_NUTTX_CUSTOM_INIT
|
||||
/**
|
||||
* Initialize the LVGL display driver for NuttX using the provided custom configuration information.
|
||||
* @param info Pointer to the lv_nuttx_t structure containing the custom configuration information for the display driver.
|
||||
* @return Pointer to the lv_display_t structure representing the initialized display driver.
|
||||
* @param dsc Pointer to the lv_nuttx_dsc_t structure containing the custom configuration for the display driver.
|
||||
* @param result Pointer to the lv_nuttx_result_t structure containing display and input device handler.
|
||||
*/
|
||||
lv_display_t * lv_nuttx_init_custom(const lv_nuttx_t * info);
|
||||
void lv_nuttx_init_custom(const lv_nuttx_dsc_t * dsc, lv_nuttx_result_t * result);
|
||||
|
||||
#endif /* LV_USE_NUTTX_CUSTOM_INIT */
|
||||
|
||||
/**********************
|
||||
|
||||
@@ -15,11 +15,12 @@
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <poll.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <nuttx/video/fb.h>
|
||||
|
||||
#include <lvgl/lvgl.h>
|
||||
#include "../../../lvgl.h"
|
||||
#include "../../lvgl_private.h"
|
||||
|
||||
/*********************
|
||||
@@ -47,6 +48,7 @@ typedef struct {
|
||||
static void flush_cb(lv_display_t * disp, const lv_area_t * area, uint8_t * color_p);
|
||||
static int fbdev_get_pinfo(int fd, struct fb_planeinfo_s * pinfo);
|
||||
static int fbdev_init_mem2(lv_nuttx_fb_t * dsc);
|
||||
static void _display_refr_timer_cb(lv_timer_t * tmr);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
@@ -60,10 +62,6 @@ static int fbdev_init_mem2(lv_nuttx_fb_t * dsc);
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: lv_nuttx_fbdev_create
|
||||
****************************************************************************/
|
||||
|
||||
lv_display_t * lv_nuttx_fbdev_create(void)
|
||||
{
|
||||
lv_nuttx_fb_t * dsc = lv_malloc(sizeof(lv_nuttx_fb_t));
|
||||
@@ -82,10 +80,6 @@ lv_display_t * lv_nuttx_fbdev_create(void)
|
||||
return disp;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: lv_nuttx_fbdev_set_file
|
||||
****************************************************************************/
|
||||
|
||||
int lv_nuttx_fbdev_set_file(lv_display_t * disp, const char * file)
|
||||
{
|
||||
int ret;
|
||||
@@ -95,6 +89,7 @@ int lv_nuttx_fbdev_set_file(lv_display_t * disp, const char * file)
|
||||
if(dsc->fd >= 0) close(dsc->fd);
|
||||
|
||||
/* Open the file for reading and writing*/
|
||||
|
||||
dsc->fd = open(file, O_RDWR);
|
||||
if(dsc->fd < 0) {
|
||||
LV_LOG_ERROR("Error: cannot open framebuffer device");
|
||||
@@ -127,6 +122,7 @@ int lv_nuttx_fbdev_set_file(lv_display_t * disp, const char * file)
|
||||
}
|
||||
|
||||
/* double buffer mode */
|
||||
|
||||
if(dsc->pinfo.yres_virtual == (dsc->vinfo.yres * 2)) {
|
||||
if((ret = fbdev_init_mem2(dsc)) < 0) {
|
||||
goto errout;
|
||||
@@ -135,7 +131,9 @@ int lv_nuttx_fbdev_set_file(lv_display_t * disp, const char * file)
|
||||
|
||||
lv_display_set_draw_buffers(disp, dsc->mem, dsc->mem2,
|
||||
(dsc->pinfo.stride * dsc->vinfo.yres), LV_DISP_RENDER_MODE_DIRECT);
|
||||
lv_display_set_user_data(disp, (void *)(uintptr_t)(dsc->fd));
|
||||
lv_display_set_resolution(disp, dsc->vinfo.xres, dsc->vinfo.yres);
|
||||
lv_timer_set_cb(disp->refr_timer, _display_refr_timer_cb);
|
||||
|
||||
LV_LOG_INFO("Resolution is set to %dx%d at %ddpi", dsc->vinfo.xres, dsc->vinfo.yres, lv_display_get_dpi(disp));
|
||||
return 0;
|
||||
@@ -150,11 +148,31 @@ errout:
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
static void _display_refr_timer_cb(lv_timer_t * tmr)
|
||||
{
|
||||
lv_display_t * disp = lv_timer_get_user_data(tmr);
|
||||
lv_nuttx_fb_t * dsc = lv_display_get_driver_data(disp);
|
||||
struct pollfd pfds[1];
|
||||
|
||||
lv_memset(pfds, 0, sizeof(pfds));
|
||||
pfds[0].fd = dsc->fd;
|
||||
pfds[0].events = POLLOUT;
|
||||
|
||||
/* Query free fb to draw */
|
||||
|
||||
if(poll(pfds, 1, 0) < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(pfds[0].revents & POLLOUT) {
|
||||
_lv_display_refr_timer(tmr);
|
||||
}
|
||||
}
|
||||
|
||||
static void flush_cb(lv_display_t * disp, const lv_area_t * area, uint8_t * color_p)
|
||||
{
|
||||
lv_nuttx_fb_t * dsc = lv_display_get_driver_data(disp);
|
||||
|
||||
|
||||
/* Skip the non-last flush */
|
||||
|
||||
if(!lv_display_flush_is_last(disp)) {
|
||||
@@ -171,6 +189,7 @@ static void flush_cb(lv_display_t * disp, const lv_area_t * area, uint8_t * colo
|
||||
|
||||
#if defined(CONFIG_FB_UPDATE)
|
||||
/*May be some direct update command is required*/
|
||||
|
||||
struct fb_area_s fb_area;
|
||||
fb_area.x = area->x1;
|
||||
fb_area.y = area->y1;
|
||||
@@ -182,6 +201,7 @@ static void flush_cb(lv_display_t * disp, const lv_area_t * area, uint8_t * colo
|
||||
#endif
|
||||
|
||||
/* double framebuffer */
|
||||
|
||||
if(dsc->mem2 != NULL) {
|
||||
if(disp->buf_act == disp->buf_1) {
|
||||
dsc->pinfo.yoffset = 0;
|
||||
@@ -197,11 +217,6 @@ static void flush_cb(lv_display_t * disp, const lv_area_t * area, uint8_t * colo
|
||||
lv_display_flush_ready(disp);
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* Name: fbdev_get_pinfo
|
||||
****************************************************************************/
|
||||
|
||||
static int fbdev_get_pinfo(int fd, FAR struct fb_planeinfo_s * pinfo)
|
||||
{
|
||||
if(ioctl(fd, FBIOGET_PLANEINFO, (unsigned long)((uintptr_t)pinfo)) < 0) {
|
||||
@@ -216,7 +231,7 @@ static int fbdev_get_pinfo(int fd, FAR struct fb_planeinfo_s * pinfo)
|
||||
LV_LOG_INFO(" display: %u", pinfo->display);
|
||||
LV_LOG_INFO(" bpp: %u", pinfo->bpp);
|
||||
|
||||
/* Only these pixel depths are supported. viinfo.fmt is ignored, only
|
||||
/* Only these pixel depths are supported. vinfo.fmt is ignored, only
|
||||
* certain color formats are supported.
|
||||
*/
|
||||
|
||||
@@ -229,17 +244,13 @@ static int fbdev_get_pinfo(int fd, FAR struct fb_planeinfo_s * pinfo)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: fbdev_init_mem2
|
||||
****************************************************************************/
|
||||
|
||||
static int fbdev_init_mem2(lv_nuttx_fb_t * dsc)
|
||||
{
|
||||
uintptr_t buf_offset;
|
||||
struct fb_planeinfo_s pinfo;
|
||||
int ret;
|
||||
|
||||
memset(&pinfo, 0, sizeof(pinfo));
|
||||
lv_memset(&pinfo, 0, sizeof(pinfo));
|
||||
|
||||
/* Get display[1] planeinfo */
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ extern "C" {
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "lv_nuttx_entry.h"
|
||||
#include "../../display/lv_display.h"
|
||||
|
||||
#if LV_USE_NUTTX
|
||||
|
||||
@@ -29,8 +29,17 @@ extern "C" {
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Create a new display with NuttX backend.
|
||||
*/
|
||||
lv_display_t * lv_nuttx_fbdev_create(void);
|
||||
|
||||
/**
|
||||
* Initialize display with specified framebuffer device
|
||||
* @param disp pointer to display with NuttX backend
|
||||
* @param file the name of framebuffer device
|
||||
*/
|
||||
int lv_nuttx_fbdev_set_file(lv_display_t * disp, const char * file);
|
||||
|
||||
/**********************
|
||||
|
||||
@@ -9,6 +9,8 @@
|
||||
|
||||
#include "lv_nuttx_lcd.h"
|
||||
|
||||
#if LV_USE_NUTTX
|
||||
|
||||
#if LV_USE_NUTTX_LCD
|
||||
|
||||
#include <sys/ioctl.h>
|
||||
@@ -20,7 +22,7 @@
|
||||
#include <fcntl.h>
|
||||
#include <nuttx/lcd/lcd_dev.h>
|
||||
|
||||
#include <lvgl/lvgl.h>
|
||||
#include "../../../lvgl.h"
|
||||
#include "../../lvgl_private.h"
|
||||
|
||||
/*********************
|
||||
@@ -134,7 +136,7 @@ static void rounder_cb(lv_event_t * e)
|
||||
static void flush_cb(lv_display_t * disp, const lv_area_t * area_p,
|
||||
uint8_t * color_p)
|
||||
{
|
||||
lv_nuttx_lcd_t * lcd = disp->user_data;
|
||||
lv_nuttx_lcd_t * lcd = disp->driver_data;
|
||||
|
||||
lcd->area.row_start = area_p->y1;
|
||||
lcd->area.row_end = area_p->y2;
|
||||
@@ -198,9 +200,12 @@ static lv_display_t * lcd_init(int fd, int hor_res, int ver_res)
|
||||
lv_display_set_draw_buffers(lcd->disp, draw_buf, draw_buf_2, buf_size, render_mode);
|
||||
lv_display_set_flush_cb(lcd->disp, flush_cb);
|
||||
lv_event_add(&lcd->disp->event_list, rounder_cb, LV_EVENT_INVALIDATE_AREA, lcd);
|
||||
lcd->disp->user_data = lcd;
|
||||
lcd->disp->driver_data = lcd;
|
||||
lcd->disp->user_data = (void *)(uintptr_t)fd;
|
||||
|
||||
return lcd->disp;
|
||||
}
|
||||
|
||||
#endif /*LV_USE_NUTTX_LCD*/
|
||||
|
||||
#endif /* LV_USE_NUTTX*/
|
||||
|
||||
@@ -14,7 +14,9 @@ extern "C" {
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "lv_nuttx_entry.h"
|
||||
#include "../../display/lv_display.h"
|
||||
|
||||
#if LV_USE_NUTTX
|
||||
|
||||
#if LV_USE_NUTTX_LCD
|
||||
|
||||
@@ -38,6 +40,8 @@ lv_display_t * lv_nuttx_lcd_create(const char * dev_path);
|
||||
|
||||
#endif /* LV_USE_NUTTX_LCD */
|
||||
|
||||
#endif /* LV_USE_NUTTX*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
297
src/dev/nuttx/lv_nuttx_libuv.c
Normal file
297
src/dev/nuttx/lv_nuttx_libuv.c
Normal file
@@ -0,0 +1,297 @@
|
||||
/**
|
||||
* @file lv_nuttx_libuv.c
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_nuttx_libuv.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "../../../lvgl.h"
|
||||
#include "../../lvgl_private.h"
|
||||
|
||||
#if LV_USE_NUTTX
|
||||
|
||||
#if LV_USE_NUTTX_LIBUV
|
||||
#include <uv.h>
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
typedef struct {
|
||||
int fd;
|
||||
bool polling;
|
||||
uv_poll_t fb_poll;
|
||||
} lv_nuttx_uv_fb_ctx_t;
|
||||
|
||||
typedef struct {
|
||||
int fd;
|
||||
uv_poll_t input_poll;
|
||||
} lv_nuttx_uv_input_ctx_t;
|
||||
|
||||
typedef struct {
|
||||
uv_timer_t uv_timer;
|
||||
lv_nuttx_uv_fb_ctx_t fb_ctx;
|
||||
lv_nuttx_uv_input_ctx_t input_ctx;
|
||||
} lv_nuttx_uv_ctx_t;
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
static void lv_nuttx_uv_timer_cb(uv_timer_t * handle);
|
||||
static int lv_nuttx_uv_timer_init(lv_nuttx_uv_t * uv_info, lv_nuttx_uv_ctx_t * uv_ctx);
|
||||
static void lv_nuttx_uv_timer_deinit(lv_nuttx_uv_ctx_t * uv_ctx);
|
||||
|
||||
static void lv_nuttx_uv_disp_poll_cb(uv_poll_t * handle, int status, int events);
|
||||
static void lv_nuttx_uv_disp_refr_req_cb(lv_event_t * e);
|
||||
static int lv_nuttx_uv_fb_init(lv_nuttx_uv_t * uv_info, lv_nuttx_uv_fb_ctx_t * fb_ctx);
|
||||
static void lv_nuttx_uv_fb_deinit(lv_nuttx_uv_fb_ctx_t * fb_ctx);
|
||||
|
||||
static void lv_nuttx_uv_input_poll_cb(uv_poll_t * handle, int status, int events);
|
||||
static int lv_nuttx_uv_input_init(lv_nuttx_uv_t * uv_info, lv_nuttx_uv_input_ctx_t * input_ctx);
|
||||
static void lv_nuttx_uv_input_deinit(lv_nuttx_uv_input_ctx_t * input_ctx);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
void * lv_nuttx_uv_init(lv_nuttx_uv_t * uv_info)
|
||||
{
|
||||
lv_nuttx_uv_ctx_t * uv_ctx;
|
||||
int ret;
|
||||
|
||||
uv_ctx = lv_malloc(sizeof(lv_nuttx_uv_ctx_t));
|
||||
LV_ASSERT_MALLOC(uv_ctx);
|
||||
if(uv_ctx == NULL) return NULL;
|
||||
lv_memset(uv_ctx, 0, sizeof(lv_nuttx_uv_ctx_t));
|
||||
|
||||
if((ret = lv_nuttx_uv_timer_init(uv_info, uv_ctx)) < 0) {
|
||||
LV_LOG_ERROR("lv_nuttx_uv_timer_init fail : %d", ret);
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
if((ret = lv_nuttx_uv_fb_init(uv_info, &uv_ctx->fb_ctx)) < 0) {
|
||||
LV_LOG_ERROR("lv_nuttx_uv_fb_init fail : %d", ret);
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
if((ret = lv_nuttx_uv_input_init(uv_info, &uv_ctx->input_ctx)) < 0) {
|
||||
LV_LOG_ERROR("lv_nuttx_uv_input_init fail : %d", ret);
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
return uv_ctx;
|
||||
|
||||
err_out:
|
||||
lv_free(uv_ctx);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void lv_nuttx_uv_deinit(void ** data)
|
||||
{
|
||||
lv_nuttx_uv_ctx_t * uv_ctx = *data;
|
||||
|
||||
if(uv_ctx == NULL) return;
|
||||
lv_nuttx_uv_input_deinit(&uv_ctx->input_ctx);
|
||||
lv_nuttx_uv_fb_deinit(&uv_ctx->fb_ctx);
|
||||
lv_nuttx_uv_timer_deinit(uv_ctx);
|
||||
|
||||
lv_free(uv_ctx);
|
||||
*data = NULL;
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
static void lv_nuttx_uv_timer_cb(uv_timer_t * handle)
|
||||
{
|
||||
uint32_t sleep_ms;
|
||||
|
||||
sleep_ms = lv_timer_handler();
|
||||
|
||||
if(sleep_ms == LV_NO_TIMER_READY) {
|
||||
uv_timer_stop(handle);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Prevent busy loops. */
|
||||
|
||||
if(sleep_ms == 0) {
|
||||
sleep_ms = 1;
|
||||
}
|
||||
|
||||
LV_LOG_TRACE("sleep_ms = %" PRIu32, sleep_ms);
|
||||
uv_timer_start(handle, lv_nuttx_uv_timer_cb, sleep_ms, 0);
|
||||
}
|
||||
|
||||
static void lv_nuttx_uv_timer_resume(void * data)
|
||||
{
|
||||
uv_timer_t * timer = (uv_timer_t *)data;
|
||||
if(timer)
|
||||
uv_timer_start(timer, lv_nuttx_uv_timer_cb, 0, 0);
|
||||
}
|
||||
|
||||
static int lv_nuttx_uv_timer_init(lv_nuttx_uv_t * uv_info, lv_nuttx_uv_ctx_t * uv_ctx)
|
||||
{
|
||||
uv_loop_t * loop = uv_info->loop;
|
||||
|
||||
LV_ASSERT_NULL(uv_ctx);
|
||||
LV_ASSERT_NULL(loop);
|
||||
|
||||
uv_timer_init(loop, &uv_ctx->uv_timer);
|
||||
uv_timer_start(&uv_ctx->uv_timer, lv_nuttx_uv_timer_cb, 1, 1);
|
||||
|
||||
lv_timer_handler_set_resume_cb(lv_nuttx_uv_timer_resume, &uv_ctx->uv_timer);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void lv_nuttx_uv_timer_deinit(lv_nuttx_uv_ctx_t * uv_ctx)
|
||||
{
|
||||
uv_close((uv_handle_t *)&uv_ctx->uv_timer, NULL);
|
||||
}
|
||||
|
||||
static void lv_nuttx_uv_disp_poll_cb(uv_poll_t * handle, int status, int events)
|
||||
{
|
||||
lv_nuttx_uv_fb_ctx_t * fb_ctx = (lv_nuttx_uv_fb_ctx_t *)(handle->data);
|
||||
|
||||
LV_UNUSED(status);
|
||||
LV_UNUSED(events);
|
||||
uv_poll_stop(handle);
|
||||
_lv_display_refr_timer(NULL);
|
||||
fb_ctx->polling = false;
|
||||
}
|
||||
|
||||
static void lv_nuttx_uv_disp_refr_req_cb(lv_event_t * e)
|
||||
{
|
||||
lv_nuttx_uv_fb_ctx_t * fb_ctx = lv_event_get_user_data(e);
|
||||
|
||||
if(fb_ctx->polling) {
|
||||
return;
|
||||
}
|
||||
fb_ctx->polling = true;
|
||||
uv_poll_start(&fb_ctx->fb_poll, UV_WRITABLE, lv_nuttx_uv_disp_poll_cb);
|
||||
}
|
||||
|
||||
static int lv_nuttx_uv_fb_init(lv_nuttx_uv_t * uv_info, lv_nuttx_uv_fb_ctx_t * fb_ctx)
|
||||
{
|
||||
uv_loop_t * loop = uv_info->loop;
|
||||
lv_display_t * disp = uv_info->disp;
|
||||
|
||||
LV_ASSERT_NULL(fb_ctx);
|
||||
LV_ASSERT_NULL(disp);
|
||||
LV_ASSERT_NULL(loop);
|
||||
|
||||
fb_ctx->fd = (uintptr_t)lv_display_get_user_data(disp);
|
||||
|
||||
if(fb_ctx->fd <= 0) {
|
||||
LV_LOG_INFO("skip uv fb init.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(!disp->refr_timer) {
|
||||
LV_LOG_ERROR("disp->refr_timer is NULL");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Remove default refr timer. */
|
||||
|
||||
lv_timer_del(disp->refr_timer);
|
||||
disp->refr_timer = NULL;
|
||||
|
||||
fb_ctx->fb_poll.data = fb_ctx;
|
||||
uv_poll_init(loop, &fb_ctx->fb_poll, fb_ctx->fd);
|
||||
uv_poll_start(&fb_ctx->fb_poll, UV_WRITABLE, lv_nuttx_uv_disp_poll_cb);
|
||||
|
||||
LV_LOG_INFO("lvgl fb loop start OK");
|
||||
|
||||
/* Register for the invalidate area event */
|
||||
|
||||
lv_event_add(&disp->event_list, lv_nuttx_uv_disp_refr_req_cb, LV_EVENT_REFR_REQUEST, fb_ctx);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void lv_nuttx_uv_fb_deinit(lv_nuttx_uv_fb_ctx_t * fb_ctx)
|
||||
{
|
||||
if(fb_ctx->fd > 0) {
|
||||
uv_close((uv_handle_t *)&fb_ctx->fb_poll, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static void lv_nuttx_uv_input_poll_cb(uv_poll_t * handle, int status, int events)
|
||||
{
|
||||
lv_indev_t * indev = (lv_indev_t *)(handle->data);
|
||||
|
||||
if(status < 0) {
|
||||
LV_LOG_WARN("input poll error: %s ", uv_strerror(status));
|
||||
return;
|
||||
}
|
||||
|
||||
if(events & UV_READABLE) {
|
||||
lv_indev_read(indev);
|
||||
}
|
||||
}
|
||||
|
||||
static int lv_nuttx_uv_input_init(lv_nuttx_uv_t * uv_info, lv_nuttx_uv_input_ctx_t * input_ctx)
|
||||
{
|
||||
uv_loop_t * loop = uv_info->loop;
|
||||
lv_indev_t * indev = uv_info->indev;
|
||||
|
||||
if(indev == NULL) {
|
||||
LV_LOG_INFO("skip uv input init.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
LV_ASSERT_NULL(input_ctx);
|
||||
LV_ASSERT_NULL(loop);
|
||||
|
||||
if(!indev->read_timer) {
|
||||
LV_LOG_ERROR("indev->read_timer is NULL");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
input_ctx->fd = (uintptr_t)lv_indev_get_user_data(indev);
|
||||
if(input_ctx->fd <= 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Remove default indev timer. */
|
||||
|
||||
lv_timer_del(indev->read_timer);
|
||||
indev->read_timer = NULL;
|
||||
|
||||
input_ctx->input_poll.data = indev;
|
||||
uv_poll_init(loop, &input_ctx->input_poll, input_ctx->fd);
|
||||
uv_poll_start(&input_ctx->input_poll, UV_READABLE, lv_nuttx_uv_input_poll_cb);
|
||||
|
||||
LV_LOG_INFO("lvgl input loop start OK");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void lv_nuttx_uv_input_deinit(lv_nuttx_uv_input_ctx_t * input_ctx)
|
||||
{
|
||||
if(input_ctx->fd > 0) {
|
||||
uv_close((uv_handle_t *)&input_ctx->input_poll, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /*LV_USE_NUTTX_LIBUV*/
|
||||
|
||||
#endif /*LV_USE_NUTTX*/
|
||||
66
src/dev/nuttx/lv_nuttx_libuv.h
Normal file
66
src/dev/nuttx/lv_nuttx_libuv.h
Normal file
@@ -0,0 +1,66 @@
|
||||
/**
|
||||
* @file lv_nuttx_libuv.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_NUTTX_LIBUV_H
|
||||
#define LV_NUTTX_LIBUV_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "../../display/lv_display.h"
|
||||
#include "../../indev/lv_indev.h"
|
||||
|
||||
#if LV_USE_NUTTX
|
||||
|
||||
#if LV_USE_NUTTX_LIBUV
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
typedef struct {
|
||||
void * loop;
|
||||
lv_display_t * disp;
|
||||
lv_indev_t * indev;
|
||||
} lv_nuttx_uv_t;
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Initialize the uv_loop using the provided configuration information.
|
||||
* @param uv_info Pointer to the lv_nuttx_uv_t structure to be initialized.
|
||||
*/
|
||||
void * lv_nuttx_uv_init(lv_nuttx_uv_t * uv_info);
|
||||
|
||||
/**
|
||||
* Deinitialize the uv_loop configuration for NuttX porting layer.
|
||||
* @param data Pointer to user data.
|
||||
*/
|
||||
void lv_nuttx_uv_deinit(void ** data);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#endif /*LV_USE_NUTTX_LIBUV*/
|
||||
|
||||
#endif /*LV_USE_NUTTX*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /*LV_NUTTX_LIBUV_H*/
|
||||
@@ -8,6 +8,9 @@
|
||||
*********************/
|
||||
|
||||
#include "lv_nuttx_touchscreen.h"
|
||||
|
||||
#if LV_USE_NUTTX
|
||||
|
||||
#if LV_USE_NUTTX_TOUCHSCREEN
|
||||
|
||||
#include <sys/types.h>
|
||||
@@ -82,7 +85,7 @@ lv_indev_t * lv_nuttx_touchscreen_create(const char * dev_path)
|
||||
|
||||
static void touchscreen_read(lv_indev_t * drv, lv_indev_data_t * data)
|
||||
{
|
||||
lv_nuttx_touchscreen_t * touchscreen = drv->user_data;
|
||||
lv_nuttx_touchscreen_t * touchscreen = drv->driver_data;
|
||||
struct touch_sample_s sample;
|
||||
|
||||
/* Read one sample */
|
||||
@@ -132,9 +135,12 @@ static lv_indev_t * touchscreen_init(int fd)
|
||||
touchscreen->indev_drv = lv_indev_create();
|
||||
touchscreen->indev_drv->type = LV_INDEV_TYPE_POINTER;
|
||||
touchscreen->indev_drv->read_cb = touchscreen_read;
|
||||
touchscreen->indev_drv->user_data = touchscreen;
|
||||
touchscreen->indev_drv->driver_data = touchscreen;
|
||||
touchscreen->indev_drv->user_data = (void *)(uintptr_t)fd;
|
||||
|
||||
return touchscreen->indev_drv;
|
||||
}
|
||||
|
||||
#endif /*LV_USE_NUTTX_TOUCHSCREEN*/
|
||||
|
||||
#endif /* LV_USE_NUTTX*/
|
||||
|
||||
@@ -18,7 +18,9 @@ extern "C" {
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "lv_nuttx_entry.h"
|
||||
#include "../../indev/lv_indev.h"
|
||||
|
||||
#if LV_USE_NUTTX
|
||||
|
||||
#if LV_USE_NUTTX_TOUCHSCREEN
|
||||
|
||||
@@ -34,6 +36,10 @@ extern "C" {
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Initialize indev with specified input device.
|
||||
* @param dev_path path of input device
|
||||
*/
|
||||
lv_indev_t * lv_nuttx_touchscreen_create(const char * dev_path);
|
||||
|
||||
/**********************
|
||||
@@ -42,6 +48,8 @@ lv_indev_t * lv_nuttx_touchscreen_create(const char * dev_path);
|
||||
|
||||
#endif /* LV_USE_NUTTX_TOUCHSCREEN */
|
||||
|
||||
#endif /* LV_USE_NUTTX*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
@@ -2499,47 +2499,58 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*Use Nuttx custom init API to open window and handle touchscreen*/
|
||||
#ifndef LV_USE_NUTTX_CUSTOM_INIT
|
||||
#ifdef CONFIG_LV_USE_NUTTX_CUSTOM_INIT
|
||||
#define LV_USE_NUTTX_CUSTOM_INIT CONFIG_LV_USE_NUTTX_CUSTOM_INIT
|
||||
#else
|
||||
#define LV_USE_NUTTX_CUSTOM_INIT 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*Driver for /dev/lcd*/
|
||||
#ifndef LV_USE_NUTTX_LCD
|
||||
#ifdef CONFIG_LV_USE_NUTTX_LCD
|
||||
#define LV_USE_NUTTX_LCD CONFIG_LV_USE_NUTTX_LCD
|
||||
#else
|
||||
#define LV_USE_NUTTX_LCD 0
|
||||
#endif
|
||||
#endif
|
||||
#if LV_USE_NUTTX_LCD
|
||||
#ifndef LV_NUTTX_LCD_BUFFER_COUNT
|
||||
#ifdef CONFIG_LV_NUTTX_LCD_BUFFER_COUNT
|
||||
#define LV_NUTTX_LCD_BUFFER_COUNT CONFIG_LV_NUTTX_LCD_BUFFER_COUNT
|
||||
#if LV_USE_NUTTX
|
||||
#ifndef LV_USE_NUTTX_LIBUV
|
||||
#ifdef CONFIG_LV_USE_NUTTX_LIBUV
|
||||
#define LV_USE_NUTTX_LIBUV CONFIG_LV_USE_NUTTX_LIBUV
|
||||
#else
|
||||
#define LV_NUTTX_LCD_BUFFER_COUNT 0
|
||||
#define LV_USE_NUTTX_LIBUV 0
|
||||
#endif
|
||||
#endif
|
||||
#ifndef LV_NUTTX_LCD_BUFFER_SIZE
|
||||
#ifdef CONFIG_LV_NUTTX_LCD_BUFFER_SIZE
|
||||
#define LV_NUTTX_LCD_BUFFER_SIZE CONFIG_LV_NUTTX_LCD_BUFFER_SIZE
|
||||
|
||||
/*Use Nuttx custom init API to open window and handle touchscreen*/
|
||||
#ifndef LV_USE_NUTTX_CUSTOM_INIT
|
||||
#ifdef CONFIG_LV_USE_NUTTX_CUSTOM_INIT
|
||||
#define LV_USE_NUTTX_CUSTOM_INIT CONFIG_LV_USE_NUTTX_CUSTOM_INIT
|
||||
#else
|
||||
#define LV_NUTTX_LCD_BUFFER_SIZE 60
|
||||
#define LV_USE_NUTTX_CUSTOM_INIT 0
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*Driver for /dev/input*/
|
||||
#ifndef LV_USE_NUTTX_TOUCHSCREEN
|
||||
#ifdef CONFIG_LV_USE_NUTTX_TOUCHSCREEN
|
||||
#define LV_USE_NUTTX_TOUCHSCREEN CONFIG_LV_USE_NUTTX_TOUCHSCREEN
|
||||
#else
|
||||
#define LV_USE_NUTTX_TOUCHSCREEN 0
|
||||
/*Driver for /dev/lcd*/
|
||||
#ifndef LV_USE_NUTTX_LCD
|
||||
#ifdef CONFIG_LV_USE_NUTTX_LCD
|
||||
#define LV_USE_NUTTX_LCD CONFIG_LV_USE_NUTTX_LCD
|
||||
#else
|
||||
#define LV_USE_NUTTX_LCD 0
|
||||
#endif
|
||||
#endif
|
||||
#if LV_USE_NUTTX_LCD
|
||||
#ifndef LV_NUTTX_LCD_BUFFER_COUNT
|
||||
#ifdef CONFIG_LV_NUTTX_LCD_BUFFER_COUNT
|
||||
#define LV_NUTTX_LCD_BUFFER_COUNT CONFIG_LV_NUTTX_LCD_BUFFER_COUNT
|
||||
#else
|
||||
#define LV_NUTTX_LCD_BUFFER_COUNT 0
|
||||
#endif
|
||||
#endif
|
||||
#ifndef LV_NUTTX_LCD_BUFFER_SIZE
|
||||
#ifdef CONFIG_LV_NUTTX_LCD_BUFFER_SIZE
|
||||
#define LV_NUTTX_LCD_BUFFER_SIZE CONFIG_LV_NUTTX_LCD_BUFFER_SIZE
|
||||
#else
|
||||
#define LV_NUTTX_LCD_BUFFER_SIZE 60
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*Driver for /dev/input*/
|
||||
#ifndef LV_USE_NUTTX_TOUCHSCREEN
|
||||
#ifdef CONFIG_LV_USE_NUTTX_TOUCHSCREEN
|
||||
#define LV_USE_NUTTX_TOUCHSCREEN CONFIG_LV_USE_NUTTX_TOUCHSCREEN
|
||||
#else
|
||||
#define LV_USE_NUTTX_TOUCHSCREEN 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/*Driver for /dev/dri/card*/
|
||||
|
||||
Reference in New Issue
Block a user