Raspberry Pi Official 7" Touchscreen and LittlevGL

The Official Raspberry Pi 7" Touchscreen is very cost effective device which can turn a RaPi into a very sophisticated GUI for all sorts of home projects.

This article is about using the touchscreen as a dedicated interface to home-brew code on a head-less RaPi, that is, a Pi which does not utilise the X-Windows GUI.

A ready-to-compile repository is available here.

After a bit of research I have found a great library which provides elegant user interface objects, it's called LittlevGL and comes free of charge. The library is written in C and designed to work with embedded devices. Here is a link to the library website.

The library comes with pretty good install instructions and it's easy to get the demo graphics to display.

The documentation is located here.

The LCD interface of the screen is connected to the onboard DSI connector and the driver is already part of Raspbian. LittlevGL uses the frame buffer device /dev/fb0 to drive the screen. 
The touch interface is connected to the RaPi via I2C interface but Raspbian provides the hardware level interface and presents the touch events at /dev/input/event0.

The config files need the following changes:

Near the top of the various config files you will need to change:

#if 0

to

#if 1

This will step is required in each of the config files.

lv_conf.h 

#define LV_HOR_RES (800)
#define LV_VER_RES (480)
#define LV_COLOR_DEPTH 32 

lv_drv_config.h add the following lines somewhere near the top of the file:

#define USE_FBDEV 1
#define USE_EVDEV 1

lv_ex_conf.h:

#define USE_LV_DEMO 1

Since the upgrade to LVGL V7 you will also need to configure and initialise the display buffer:

#define DISP_BUF_SIZE 384000;   // 480x800
static lv_disp_buf_t dispatch_buf;
static lv_color_t buf1[DISP_BUF_SIZE];
static lv_color_t buf2[DISP_BUF_SIZE];
lv_disp_buf_init(&disp_buf, buf1, buf2, DISP_BUF_SIZE];

It is important that the buffer is fully initialised before display driver initialisation.

lv_init();
fbdev_init();
lv_disp_drv_t disp_drv;
lv_disp_drv_init(&disp_drv);
disp_drv.buffer = &disp_drv;
disp_drv.flush_cb = fbdev_flush;
lv_disp_t *disp;
disp = lv_disp_drv_register(&disp_drv);

This should sufficient to get the screen output working. First with the "Hello World" example and then with the demo_create() function. 
To get touch input working add the following lines after lv_init() in main().

evdev_init();
lv_indev_drv_t indev_drv;
lv_indev_drv_init(&indev_drv);
indev_drv.type = LV_INDEV_TYPE_POINTER;
indev_drv.read = evdev_read;
lv_indev_drv_register(&indev_drv);

The porting guide provides some information on adding touch input.

With those modifications the touch screen should now be functional.

One final step is required to eliminate the blinking cursor which keep re-appearing on the screen:

add the following into /boot/cmdline.txt

vt.global_cursor_default=0