From 3638f1c3fa6be35362d8e23561ebb81cdc3b0d84 Mon Sep 17 00:00:00 2001 From: Brennan Ashton Date: Mon, 15 Feb 2021 01:05:04 -0800 Subject: [PATCH] lvgldemo: Add support for lcddev This provides an adaptor for using lvgl with the lcddev in addition to the fbdev. As part of this it also fixes a compilation error when fbdev was used with CONFIG_FB_UPDATE. There is also a monitoring callback enabled for monitoring the performance of the demo. --- examples/lvgldemo/Makefile | 2 +- examples/lvgldemo/fbdev.c | 411 +++++++---------------------------- examples/lvgldemo/fbdev.h | 10 +- examples/lvgldemo/lcddev.c | 197 +++++++++++++++++ examples/lvgldemo/lcddev.h | 46 ++++ examples/lvgldemo/lvgldemo.c | 51 ++++- 6 files changed, 370 insertions(+), 347 deletions(-) create mode 100644 examples/lvgldemo/lcddev.c create mode 100644 examples/lvgldemo/lcddev.h diff --git a/examples/lvgldemo/Makefile b/examples/lvgldemo/Makefile index 64d609b91..07c8a3503 100644 --- a/examples/lvgldemo/Makefile +++ b/examples/lvgldemo/Makefile @@ -52,7 +52,7 @@ MODULE = $(CONFIG_EXAMPLES_LVGLDEMO) # LittleVGL demo Example -CSRCS += fbdev.c tp.c tp_cal.c +CSRCS += fbdev.c lcddev.c tp.c tp_cal.c # static common assets used in mutiple example diff --git a/examples/lvgldemo/fbdev.c b/examples/lvgldemo/fbdev.c index c7f59e7f9..1b6c00dec 100644 --- a/examples/lvgldemo/fbdev.c +++ b/examples/lvgldemo/fbdev.c @@ -48,6 +48,7 @@ #include #include #include +#include #include #include @@ -82,109 +83,6 @@ struct fb_state_s state; * Public Functions ****************************************************************************/ -/**************************************************************************** - * Name: fbdev_init - * - * Description: - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - ****************************************************************************/ - -int fbdev_init(void) -{ - FAR const char *fbdev = "/dev/fb0"; - int ret; - - /* Open the framebuffer driver */ - - state.fd = open(fbdev, O_RDWR); - if (state.fd < 0) - { - int errcode = errno; - fprintf(stderr, "ERROR: Failed to open %s: %d\n", fbdev, errcode); - return EXIT_FAILURE; - } - - /* Get the characteristics of the framebuffer */ - - ret = ioctl(state.fd, FBIOGET_VIDEOINFO, - (unsigned long)((uintptr_t)&state.vinfo)); - if (ret < 0) - { - int errcode = errno; - - fprintf(stderr, "ERROR: ioctl(FBIOGET_VIDEOINFO) failed: %d\n", - errcode); - close(state.fd); - return EXIT_FAILURE; - } - - printf("VideoInfo:\n"); - printf(" fmt: %u\n", state.vinfo.fmt); - printf(" xres: %u\n", state.vinfo.xres); - printf(" yres: %u\n", state.vinfo.yres); - printf(" nplanes: %u\n", state.vinfo.nplanes); - - ret = ioctl(state.fd, FBIOGET_PLANEINFO, - (unsigned long)((uintptr_t)&state.pinfo)); - if (ret < 0) - { - int errcode = errno; - fprintf(stderr, "ERROR: ioctl(FBIOGET_PLANEINFO) failed: %d\n", - errcode); - close(state.fd); - return EXIT_FAILURE; - } - - printf("PlaneInfo (plane 0):\n"); - printf(" fbmem: %p\n", state.pinfo.fbmem); - printf(" fblen: %lu\n", (unsigned long)state.pinfo.fblen); - printf(" stride: %u\n", state.pinfo.stride); - printf(" display: %u\n", state.pinfo.display); - printf(" bpp: %u\n", state.pinfo.bpp); - - /* Only these pixel depths are supported. viinfo.fmt is ignored, only - * certain color formats are supported. - */ - - if (state.pinfo.bpp != 32 && state.pinfo.bpp != 16 && - state.pinfo.bpp != 8 && state.pinfo.bpp != 1) - { - fprintf(stderr, "ERROR: bpp=%u not supported\n", state.pinfo.bpp); - close(state.fd); - return EXIT_FAILURE; - } - - /* mmap() the framebuffer. - * - * NOTE: In the FLAT build the frame buffer address returned by the - * FBIOGET_PLANEINFO IOCTL command will be the same as the framebuffer - * address. mmap(), however, is the preferred way to get the framebuffer - * address because in the KERNEL build, it will perform the necessary - * address mapping to make the memory accessible to the application. - */ - - state.fbmem = mmap(NULL, state.pinfo.fblen, PROT_READ | PROT_WRITE, - MAP_SHARED | MAP_FILE, state.fd, 0); - if (state.fbmem == MAP_FAILED) - { - int errcode = errno; - fprintf(stderr, "ERROR: ioctl(FBIOGET_PLANEINFO) failed: %d\n", - errcode); - close(state.fd); - return EXIT_FAILURE; - } - - printf("Mapped FB: %p\n", state.fbmem); - - return EXIT_SUCCESS; -} - /**************************************************************************** * Name: fbdev_flush * @@ -203,11 +101,11 @@ int fbdev_init(void) * ****************************************************************************/ -void fbdev_flush(struct _disp_drv_t *disp_drv, const lv_area_t *area, - lv_color_t *color_p) +static void fbdev_flush(struct _disp_drv_t *disp_drv, const lv_area_t *area, + lv_color_t *color_p) { #ifdef CONFIG_FB_UPDATE - struct fb_area_s area; + struct fb_area_s fb_area; #endif int32_t x1 = area->x1; int32_t y1 = area->y1; @@ -311,11 +209,11 @@ void fbdev_flush(struct _disp_drv_t *disp_drv, const lv_area_t *area, } #ifdef CONFIG_FB_UPDATE - area.x = act_x1; - area.y = act_y1; - area.w = act_x2 - act_x1 + 1; - area.h = act_y2 - cat_y1 + 1; - ioctl(state.fd, FBIO_UPDATE, (unsigned long)((uintptr_t)&area)); + fb_area.x = act_x1; + fb_area.y = act_y1; + fb_area.w = act_x2 - act_x1 + 1; + fb_area.h = act_y2 - act_y1 + 1; + ioctl(state.fd, FBIO_UPDATE, (unsigned long)((uintptr_t)&fb_area)); #endif /* Tell the flushing is ready */ @@ -324,252 +222,111 @@ void fbdev_flush(struct _disp_drv_t *disp_drv, const lv_area_t *area, } /**************************************************************************** - * Name: fbdev_fill - * - * Description: - * Fill an area with a color - * - * Input Parameters: - * x1 - Left coordinate - * y1 - Top coordinate - * x2 - Right coordinate - * y2 - Bottom coordinate - * color - The fill color - * - * Returned Value: - * None - * + * Public Functions ****************************************************************************/ -void fbdev_fill(int32_t x1, int32_t y1, int32_t x2, int32_t y2, - lv_color_t color) -{ -#ifdef CONFIG_FB_UPDATE - struct fb_area_s area; -#endif - int32_t act_x1; - int32_t act_y1; - int32_t act_x2; - int32_t act_y2; - long int location = 0; - - if (state.fbmem == NULL) - { - return; - } - - /* Return if the area is out the screen */ - - if (x2 < 0) - { - return; - } - - if (y2 < 0) - { - return; - } - - if (x1 > state.vinfo.xres - 1) - { - return; - } - - if (y1 > state.vinfo.yres - 1) - { - return; - } - - /* Truncate the area to the screen */ - - act_x1 = x1 < 0 ? 0 : x1; - act_y1 = y1 < 0 ? 0 : y1; - act_x2 = x2 > state.vinfo.xres - 1 ? state.vinfo.xres - 1 : x2; - act_y2 = y2 > state.vinfo.yres - 1 ? state.vinfo.yres - 1 : y2; - - if (state.pinfo.bpp == 8) - { - uint8_t *fbp8 = (uint8_t *)state.fbmem; - uint32_t x; - uint32_t y; - - for (y = act_y1; y <= act_y2; y++) - { - for (x = act_x1; x <= act_x2; x++) - { - location = x + (y * state.vinfo.xres); - fbp8[location] = color.full; - } - } - } - - if (state.pinfo.bpp == 16) - { - uint16_t *fbp16 = (uint16_t *)state.fbmem; - uint32_t x; - uint32_t y; - - for (y = act_y1; y <= act_y2; y++) - { - for (x = act_x1; x <= act_x2; x++) - { - location = x + (y * state.vinfo.xres); - fbp16[location] = color.full; - } - } - } - - if (state.pinfo.bpp == 24 || state.pinfo.bpp == 32) - { - uint32_t *fbp32 = (uint32_t *)state.fbmem; - uint32_t x; - uint32_t y; - - for (y = act_y1; y <= act_y2; y++) - { - for (x = act_x1; x <= act_x2; x++) - { - location = x + (y * state.vinfo.xres); - fbp32[location] = color.full; - } - } - } - -#ifdef CONFIG_FB_UPDATE - area.x = act_x1; - area.y = act_y1; - area.w = act_x2 - act_x1 + 1; - area.h = act_y2 - act_y1 + 1; - ioctl(state.fd, FBIO_UPDATE, (unsigned long)((uintptr_t)&area)); -#endif -} - /**************************************************************************** - * Name: fbdev_map + * Name: fbdev_init * * Description: - * Write an array of pixels (like an image) to the marked area * * Input Parameters: - * x1 - Left coordinate - * y1 - Top coordinate - * x2 - Right coordinate - * y2 - Bottom coordinate - * color_p - An array of colors + * lv_drvr -- LVGL driver interface * * Returned Value: * None * ****************************************************************************/ -void fbdev_map(int32_t x1, int32_t y1, int32_t x2, int32_t y2, - FAR const lv_color_t *color_p) +int fbdev_init(lv_disp_drv_t *lv_drvr) { -#ifdef CONFIG_FB_UPDATE - struct fb_area_s area; -#endif - int32_t act_x1; - int32_t act_y1; - int32_t act_x2; - int32_t act_y2; - long int location = 0; + FAR const char *fbdev = "/dev/fb0"; + int ret; - if (state.fbmem == NULL) + /* Open the framebuffer driver */ + + state.fd = open(fbdev, O_RDWR); + if (state.fd < 0) { - return; + int errcode = errno; + gerr("ERROR: Failed to open %s: %d\n", fbdev, errcode); + return EXIT_FAILURE; } - /* Return if the area is out the screen */ + /* Get the characteristics of the framebuffer */ - if (x2 < 0) + ret = ioctl(state.fd, FBIOGET_VIDEOINFO, + (unsigned long)((uintptr_t)&state.vinfo)); + if (ret < 0) { - return; + int errcode = errno; + + gerr("ERROR: ioctl(FBIOGET_VIDEOINFO) failed: %d\n", errcode); + close(state.fd); + state.fd = -1; + return EXIT_FAILURE; } - if (y2 < 0) + ginfo("VideoInfo:\n\tfmt: %u\n\txres: %u\n\tyres: %u\n\tnplanes: %u\n", + state.vinfo.fmt, state.vinfo.xres, state.vinfo.yres, + state.vinfo.nplanes); + + ret = ioctl(state.fd, FBIOGET_PLANEINFO, + (unsigned long)((uintptr_t)&state.pinfo)); + if (ret < 0) { - return; + int errcode = errno; + gerr("ERROR: ioctl(FBIOGET_PLANEINFO) failed: %d\n", errcode); + close(state.fd); + state.fd = -1; + return EXIT_FAILURE; } - if (x1 > state.vinfo.xres - 1) + ginfo("PlaneInfo (plane 0):\n" + "\tfbmem: %p\n\tfblen: %l\n\tstride: %u\n" + "\tdisplay: %u\n\tbpp: %u\n\t", + state.pinfo.fbmem, (unsigned long)state.pinfo.fblen, + state.pinfo.stride, state.pinfo.display, state.pinfo.bpp); + + lv_drvr->hor_res = state.vinfo.xres; + lv_drvr->ver_res = state.vinfo.yres; + lv_drvr->flush_cb = fbdev_flush; + + /* Only these pixel depths are supported. viinfo.fmt is ignored, only + * certain color formats are supported. + */ + + if (state.pinfo.bpp != 32 && state.pinfo.bpp != 16 && + state.pinfo.bpp != 8 && state.pinfo.bpp != 1) { - return; + gerr("ERROR: bpp=%u not supported\n", state.pinfo.bpp); + close(state.fd); + state.fd = -1; + return EXIT_FAILURE; } - if (y1 > state.vinfo.yres - 1) + /* mmap() the framebuffer. + * + * NOTE: In the FLAT build the frame buffer address returned by the + * FBIOGET_PLANEINFO IOCTL command will be the same as the framebuffer + * address. mmap(), however, is the preferred way to get the framebuffer + * address because in the KERNEL build, it will perform the necessary + * address mapping to make the memory accessible to the application. + */ + + state.fbmem = mmap(NULL, state.pinfo.fblen, PROT_READ | PROT_WRITE, + MAP_SHARED | MAP_FILE, state.fd, 0); + if (state.fbmem == MAP_FAILED) { - return; + int errcode = errno; + gerr("ERROR: ioctl(FBIOGET_PLANEINFO) failed: %d\n", + errcode); + close(state.fd); + state.fd = -1; + return EXIT_FAILURE; } - /* Truncate the area to the screen */ + ginfo("Mapped FB: %p\n", state.fbmem); - act_x1 = x1 < 0 ? 0 : x1; - act_y1 = y1 < 0 ? 0 : y1; - act_x2 = x2 > state.vinfo.xres - 1 ? state.vinfo.xres - 1 : x2; - act_y2 = y2 > state.vinfo.yres - 1 ? state.vinfo.yres - 1 : y2; - - if (state.pinfo.bpp == 8) - { - uint8_t *fbp8 = (uint8_t *)state.fbmem; - uint32_t x; - uint32_t y; - - for (y = act_y1; y <= act_y2; y++) - { - for (x = act_x1; x <= act_x2; x++) - { - location = x + (y * state.vinfo.xres); - fbp8[location] = color_p->full; - color_p++; - } - - color_p += x2 - act_x2; - } - } - - if (state.pinfo.bpp == 16) - { - uint16_t *fbp16 = (uint16_t *)state.fbmem; - uint32_t x; - uint32_t y; - - for (y = act_y1; y <= act_y2; y++) - { - for (x = act_x1; x <= act_x2; x++) - { - location = x + (y * state.vinfo.xres); - fbp16[location] = color_p->full; - color_p++; - } - - color_p += x2 - act_x2; - } - } - - if (state.pinfo.bpp == 24 || state.pinfo.bpp == 32) - { - uint32_t *fbp32 = (uint32_t *)state.fbmem; - uint32_t x; - uint32_t y; - - for (y = act_y1; y <= act_y2; y++) - { - for (x = act_x1; x <= act_x2; x++) - { - location = x + (y * state.vinfo.xres); - fbp32[location] = color_p->full; - color_p++; - } - - color_p += x2 - act_x2; - } - } - -#ifdef CONFIG_FB_UPDATE - area.x = act_x1; - area.y = act_y1; - area.w = act_x2 - act_x1 + 1; - area.h = act_y2 - act_y1 + 1; - ioctl(state.fd, FBIO_UPDATE, (unsigned long)((uintptr_t)&area)); -#endif + return EXIT_SUCCESS; } diff --git a/examples/lvgldemo/fbdev.h b/examples/lvgldemo/fbdev.h index a150785ad..c4f120a06 100644 --- a/examples/lvgldemo/fbdev.h +++ b/examples/lvgldemo/fbdev.h @@ -1,5 +1,5 @@ /**************************************************************************** - * apps/examples/lvgldemo/demo.h + * apps/examples/lvgldemo/fbdev.h * * Copyright (C) 2018 Gregory Nutt. All rights reserved. * Author: Gábor Kiss-Vámosi @@ -52,13 +52,7 @@ extern "C" * Public Function Prototypes ****************************************************************************/ -int fbdev_init(void); -void fbdev_flush(struct _disp_drv_t *disp_drv, const lv_area_t *area, - lv_color_t *color_p); -void fbdev_fill(int32_t x1, int32_t y1, int32_t x2, int32_t y2, - lv_color_t color); -void fbdev_map(int32_t x1, int32_t y1, int32_t x2, int32_t y2, - FAR const lv_color_t *color_p); +int fbdev_init(lv_disp_drv_t *lv_drvr); #ifdef __cplusplus } diff --git a/examples/lvgldemo/lcddev.c b/examples/lvgldemo/lcddev.c new file mode 100644 index 000000000..9b5e47e50 --- /dev/null +++ b/examples/lvgldemo/lcddev.c @@ -0,0 +1,197 @@ +/**************************************************************************** + * apps/examples/lvgldemo/lcddev.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include "lcddev.h" + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifndef LCDDEV_PATH +# define LCDDEV_PATH "/dev/lcd0" +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct lcd_state_s +{ + int fd; + struct fb_videoinfo_s vinfo; + struct lcd_planeinfo_s pinfo; + bool rotated; +}; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static struct lcd_state_s state; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lcddev_flush + * + * Description: + * Flush a buffer to the marked area. + * + * Input Parameters: + * disp_drv - LVGL driver interface + * lv_area_t - Area of the screen to be flushed + * color_p - A n array of colors + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void lcddev_flush(struct _disp_drv_t *disp_drv, const lv_area_t *area, + lv_color_t *color_p) +{ + int ret; + struct lcddev_area_s lcd_area; + + lcd_area.row_start = area->y1; + lcd_area.row_end = area->y2; + lcd_area.col_start = area->x1; + lcd_area.col_end = area->x2; + + lcd_area.data = (uint8_t *)color_p; + + ret = ioctl(state.fd, LCDDEVIO_PUTAREA, + (unsigned long)((uintptr_t)&lcd_area)); + + if (ret < 0) + { + int errcode = errno; + + gerr("ERROR: ioctl(LCDDEVIO_PUTAREA) failed: %d\n", + errcode); + close(state.fd); + return; + } + + /* Tell the flushing is ready */ + + lv_disp_flush_ready(disp_drv); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lcddev_init + * + * Description: + * Initialize LCD device. + * + * Input Parameters: + * lv_drvr -- LVGL driver interface + * + * Returned Value: + * EXIT_SUCCESS on success; EXIT_FAILURE on failure. + * + ****************************************************************************/ + +int lcddev_init(lv_disp_drv_t *lv_drvr) +{ + FAR const char *lcddev = LCDDEV_PATH; + int ret; + + /* Open the framebuffer driver */ + + state.fd = open(lcddev, 0); + if (state.fd < 0) + { + int errcode = errno; + gerr("ERROR: Failed to open %s: %d\n", state.fd, errcode); + return EXIT_FAILURE; + } + + /* Get the characteristics of the framebuffer */ + + ret = ioctl(state.fd, LCDDEVIO_GETVIDEOINFO, + (unsigned long)((uintptr_t)&state.vinfo)); + if (ret < 0) + { + int errcode = errno; + + gerr("ERROR: ioctl(LCDDEVIO_GETVIDEOINFO) failed: %d\n", errcode); + close(state.fd); + state.fd = -1; + return EXIT_FAILURE; + } + + ginfo("VideoInfo:\n\tfmt: %u\n\txres: %u\n\tyres: %u\n\tnplanes: %u\n", + state.vinfo.fmt, state.vinfo.xres, state.vinfo.yres, + state.vinfo.nplanes); + + ret = ioctl(state.fd, LCDDEVIO_GETPLANEINFO, + (unsigned long)((uintptr_t)&state.pinfo)); + if (ret < 0) + { + int errcode = errno; + gerr("ERROR: ioctl(LCDDEVIO_GETPLANEINFO) failed: %d\n", errcode); + close(state.fd); + state.fd = -1; + return EXIT_FAILURE; + } + + ginfo("PlaneInfo (plane 0):\n\tbpp: %u\n", state.pinfo.bpp); + + if (state.pinfo.bpp != CONFIG_LV_COLOR_DEPTH) + { + /* For the LCD driver we do not have a great way to translate this + * so fail to initialize. + */ + + gerr( + "ERROR: Display bpp (%u) did not match CONFIG_LV_COLOR_DEPTH (%u)\n", + state.pinfo.bpp, + CONFIG_LV_COLOR_DEPTH); + } + + lv_drvr->hor_res = state.vinfo.xres; + lv_drvr->ver_res = state.vinfo.yres; + lv_drvr->flush_cb = lcddev_flush; + + return EXIT_SUCCESS; +} diff --git a/examples/lvgldemo/lcddev.h b/examples/lvgldemo/lcddev.h new file mode 100644 index 000000000..18d5b786e --- /dev/null +++ b/examples/lvgldemo/lcddev.h @@ -0,0 +1,46 @@ +/**************************************************************************** + * apps/examples/lvgldemo/lcddev.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __APPS_EXAMPLES_LVGLDEMO_LCDDEV_H +#define __APPS_EXAMPLES_LVGLDEMO_LCDDEV_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#ifdef __cplusplus +extern "C" +{ +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +int lcddev_init(lv_disp_drv_t *lv_drvr); + +#ifdef __cplusplus +} +#endif + +#endif /* __APPS_EXAMPLES_LVGLDEMO_LCDDEV_H */ diff --git a/examples/lvgldemo/lvgldemo.c b/examples/lvgldemo/lvgldemo.c index eeb8bce6f..05d4e0941 100644 --- a/examples/lvgldemo/lvgldemo.c +++ b/examples/lvgldemo/lvgldemo.c @@ -1,5 +1,5 @@ /**************************************************************************** - * examples/lvgdemo/lvgldemo.c + * apps/examples/lvgldemo/lvgldemo.c * * Copyright (C) 2019 Gregory Nutt. All rights reserved. * Author: Gregory Nutt @@ -43,12 +43,13 @@ #include #include #include -#include #include +#include #include #include "fbdev.h" +#include "lcddev.h" #include "tp.h" #include "tp_cal.h" @@ -89,6 +90,25 @@ void lv_demo_widgets(void); * Private Functions ****************************************************************************/ +/**************************************************************************** + * Name: monitor_cb + * + * Description: + * Monitoring callback from lvgl every time the screen is flushed. + * + ****************************************************************************/ + +static void monitor_cb(lv_disp_drv_t * disp_drv, uint32_t time, uint32_t px) +{ + ginfo("%" PRIu32 " px refreshed in %" PRIu32 " ms\n", px, time); +} + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static lv_color_t buf[DISPLAY_BUFFER_SIZE]; + /**************************************************************************** * Public Functions ****************************************************************************/ @@ -109,9 +129,7 @@ void lv_demo_widgets(void); int main(int argc, FAR char *argv[]) { lv_disp_drv_t disp_drv; - lv_disp_buf_t disp_buf; - static lv_color_t buf[DISPLAY_BUFFER_SIZE]; #ifndef CONFIG_EXAMPLES_LVGLDEMO_CALIBRATE lv_point_t p[4]; @@ -149,20 +167,31 @@ int main(int argc, FAR char *argv[]) #endif #endif - /* LittlevGL initialization */ + /* LVGL initialization */ lv_init(); - /* Display interface initialization */ - - fbdev_init(); - - /* Basic LittlevGL display driver initialization */ + /* Basic LVGL display driver initialization */ lv_disp_buf_init(&disp_buf, buf, NULL, DISPLAY_BUFFER_SIZE); lv_disp_drv_init(&disp_drv); - disp_drv.flush_cb = fbdev_flush; disp_drv.buffer = &disp_buf; + disp_drv.monitor_cb = monitor_cb; + + /* Display interface initialization */ + + if (fbdev_init(&disp_drv) != EXIT_SUCCESS) + { + /* Failed to use framebuffer falling back to lcd driver */ + + if (lcddev_init(&disp_drv) != EXIT_SUCCESS) + { + /* No possible drivers left, fail */ + + return EXIT_FAILURE; + } + } + lv_disp_drv_register(&disp_drv); /* Touchpad Initialization */