C’est en lisant un article sur le blog d’Olimex, un fabricant bulgare de carte linux embarqué réputé, que j’ai découvert la bibliothèque LittlevGL. La démonstration qu’ils en faisaient sur une de leur carte équipée d’un écran tactile m’a tout de suite convaincu. Je me suis donc mis en tête de tester cette bibliothèque sur un écran tactile TFT connecté à un raspberryPi.
Introduction
Notez bien que ce qui va suivre peut fonctionner sur n’importe quelle carte supportant GNU/Linux et un écran TFT géré par le noyau. Si l’écran dispose d’une dalle tactile résistive ou capacitive, elle sera gérée aussi par le noyau. Il faut juste s’assurer que les circuits intégrés utilisés pour l’écran et le tactile ont des pilotes dans le noyau Linux.
La bibliothèque LittlevGL
Le site officiel est disponible à cette adresse : https://littlevgl.com/
Je vous conseille dans un premier temps de parcourir la page d’accueil puis de vous rendre dans l’onglet « Live Demo » où vous pourrez tester tous les « widgets » mis à disposition par cette bibliothèque. Même si cette bibliothèque se destine plutôt à des microcontrôleurs un peu costauds, elle fonctionne aussi avec le framebuffer de Linux et propose la gestion des écrans tactiles à travers la bibliothèque libinput et/ou evdev : lisez https://blog.littlevgl.com/2018-01-03/linux_fb pour le framebuffer et le code disponible sur GitHub https://github.com/littlevgl/lv_drivers/tree/master/indev pour les périphériques d’entrées (evdev et libinput pour ce qui concerne Linux).
Choix du matériel et du logiciel pour réaliser ce test
La carte sera une raspberryPi 3B+, carte SD de 16Go, alimentation officielle, clavier usb. Pour simplifier l’installation de l’écran TFT tactile, je prends un écran qui est bien supporté par le noyau Linux et qui à déjà un fragment de « device tree » disponible pour le raspberryPi. Pour savoir quels écrans sont compatibles, il suffit de parcourir le fichier « README » dans /boot/overlays d’une carte Raspbian. Pour ma part j’avais de disponible un écran TFT tactile de chez Adafruit industry : https://www.adafruit.com/product/1601 . Il date un petit peu, c’est du résistif (il existe une version à écran capacitif) mais c’est surtout ce que j’avais de disponible. De plus il est disponible dans les « overlays » pour raspberryPi. Ci-dessous l’extrait du fichier README indiqué plus haut pour cet écran:
1 2 3 4 5 6 7 |
Name: pitft28-resistive Info: Adafruit PiTFT 2.8" resistive touch screen Load: dtoverlay=pitft28-resistive,<param>=<value> Params: speed Display SPI bus speed rotate Display rotation {0,90,180,270} fps Delay between frame updates debug Debug output level {0-7} |
La version de raspbian lite utilisée pour ce test sera celle du 2019-09-26. Une fois la carte SD créée et les paramètres de bases ajustés avec raspi-config (activation ssh, changement nom et mot de passe, passage en francais), il faut éditer le fichier /boot/config.txt et rajouter la ligne « dtoverlay=pitft28-resistive » à la fin du fichier. Pour l’instant j’utilise les paramètres par défaut de cet écran. Redémarrez la raspberryPi….
Test de l’écran Adafruit PiTFT
Si tout se passe correctement, on devrait avoir un certain nombre de modules noyau chargés pour gérer cet écran. Tapons la commande « lsmod » et analysons sa sortie:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
pi@pitft:~ $ lsmod Module Size Used by bnep 20480 2 hci_uart 40960 1 ... stmpe_ts 16384 0 fb_ili9340 16384 0 fbtft 45056 1 fb_ili9340 syscopyarea 16384 1 fbtft sysfillrect 16384 1 fbtft sysimgblt 16384 1 fbtft fb_sys_fops 16384 1 fbtft evdev 24576 3 ... spi_bcm2835 20480 0 ... |
On remarque le module noyau fbtft qui permet de gérer les écrans tft de petite taille et le pilote de l’écran adafruit fb_ili9340. L’écran tactile est géré par le module stmpe_ts. L’écran est piloté à travers le bus SPI d’ou le module spi_bcm2835. Apparement, tout est chargé pour avoir un nouvel écran de disponible, on regarde donc ce que le noyau met à notre disposition comme « framebuffer » :
1 2 |
pi@pitft:~ $ ls /dev/fb* /dev/fb0 /dev/fb1 |
fb0 correspond au framebuffer de la pi donc il doit exister dans tous les cas. Le fb1 désigne un nouvel écran. Récupérons ces caractéristiques avec la commande « fbset », installez le paquetage auparavant :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
pi@pitft:~ $ sudo apt install fbset pi@pitft:~ $ fbset -i -fb /dev/fb1 mode "240x320" geometry 240 320 240 320 16 timings 0 0 0 0 0 0 0 nonstd 1 rgba 5/11,6/5,5/0,0/0 endmode Frame buffer device information: Name : fb_ili9340 Address : 0 Size : 153600 Type : PACKED PIXELS Visual : TRUECOLOR XPanStep : 0 YPanStep : 0 YWrapStep : 0 LineLength : 480 Accelerator : No |
L’écran est bien géré par le pilote fb_ili9340, sa résolution est de 320×240 pixels. Basculons la console sur cet écran puis revenons ensuite sur l’écran HDMI:
1 2 |
pi@pitft:~ $ con2fbmap 1 1 pi@pitft:~ $ con2fbmap 1 0 |
Si tout se passe correctement on peut passer à LittleVGL….
Installation, configuration et méthode de développement de la bibliothèque LittlevGL
J’ai choisi de développer à distance mon code : je travaille sur un PC fonctionnant sous Debian 9 avec l’IDE NetBeans8 (fonctionne aussi sous Microsoft Windows et Netbeans8.2). La compilation et l’exécution du code se feront sur la RPi3. Cette méthode de développement est expliquée dans cet article.
Je suis le tutoriel d’installation sur https://docs.littlevgl.com/en/html/get-started/quick-overview.html . En particulier je vais sur https://littlevgl.com/download et je télécharge les archives pour littlevGL version 6, les exemples et les pilotes (drivers) sur mon PC de développement. Je désarchive le tout dans un répertoire (par exemple /home/olivier/dev/littlevGL). Vous allez obtenir trois répertoires qui se terminent tous par « -master », renommez les répertoires en enlevant « -master ».
Créez un nouveau projet C++ avec Netbeans (par exemple TestLittlevGL). Je copie alors les répertoires « lvgl » et « lv_drivers » au niveau de mon projet. Dans le répertoire « lvgl », copiez le fichier « lv_conf_template.h » au même niveau que le répertoire lvgl et renommez-le en « lv_conf.h ». Dans le répertoire « lv_drivers », copiez le fichier « lv_drv_conf_templ.h » au même niveau que le répertoire lvgl et renommez-le en « lv_drv_conf.h ». Vous devez obtenir une arborescence qui ressemble à la suivante:

Vous pouvez suivre ce qui est indiqué sur cette page https://blog.littlevgl.com/2018-01-03/linux_fb mais elle ne semble pas tout à fait à jour. Je détaille donc mon installation.
Tout d’abord il faut éditer le fichier « lv_conf.h » et modifier les lignes suivantes:
- #if 0 /Set it to « 1 » to enable content/ : passer le ‘0’ à ‘1’ pour activer ce fichier,
- #define LV_HOR_RES_MAX (480) : je passe à 320,
- #define LV_VER_RES_MAX (320) : je passe à 240,
- #define LV_COLOR_DEPTH 16 : je laisse du 16 bits, mettre 32 si on travaille avec le framebuffer original du raspberrypi (/dev/fb0, sortie HDMI),
- toutes les lignes qui concernent les polices embarquées disponibles : #define LV_FONT_ROBOTO_12, _16, _22 et _28 passent à 1.
Il faut ensuite éditer le fichier « lv_drv_conf.h » et modifiez les lignes suivantes pour l’affichage sur l’écran tft:
- if 0 /Set it to « 1 » to enable the content/ : passer le ‘0’ à ‘1’ pour activer ce fichier,
- #define USE_FBDEV 0 : passer le ‘0’ à ‘1’ pour activer le support du framebuffer,
- #define FBDEV_PATH « /dev/fb0 » : remplacer ‘fb0’ par ‘fb1’ : nom du framebuffer de notre ecran TFT.
Pour l’instant je ne modifie rien concernant les périphériques d’entrées dans le fichier « lv_drv_conf.h ». Dans un premier temps on va se contenter d’afficher des widgets. Comme premier exemple de test, je reprend celui donné dans le lien précédent. Je donne le code ci-dessous avec une légère modification sur « #define DISP_BUF_SIZE (80*LV_HOR_RES_MAX) »:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
#include "lvgl/lvgl.h" #include "lv_drivers/display/fbdev.h" #include <unistd.h> #define DISP_BUF_SIZE (80*LV_HOR_RES_MAX) int main(void) { /*LittlevGL init*/ lv_init(); /*Linux frame buffer device init*/ fbdev_init(); /*A small buffer for LittlevGL to draw the screen's content*/ static lv_color_t buf[DISP_BUF_SIZE]; /*Initialize a descriptor for the buffer*/ static lv_disp_buf_t disp_buf; lv_disp_buf_init(&disp_buf, buf, NULL, DISP_BUF_SIZE); /*Initialize and register a display driver*/ lv_disp_drv_t disp_drv; lv_disp_drv_init(&disp_drv); disp_drv.buffer = &disp_buf; disp_drv.flush_cb = fbdev_flush; lv_disp_drv_register(&disp_drv); /*Create a "Hello world!" label*/ lv_obj_t * label = lv_label_create(lv_scr_act(), NULL); lv_label_set_text(label, "Hello world!"); lv_obj_align(label, NULL, LV_ALIGN_CENTER, 0, 0); /*Handle LitlevGL tasks (tickless mode)*/ while(1) { lv_tick_inc(5); lv_task_handler(); usleep(5000); } return 0; } |
Si vous lancez la compilation de ce projet, cela échoue car il ne trouve pas les fonctions « fbdev_xxx ». Il faut rajouter les deux répertoires « lvgl » et « lv_drivers » à l’ensemble des fichiers sources à compiler. Cela se fait en cliquant avec le bouton droit sur le nom du projet et en choisissant le menu « Add existing items from folders » (ma version de Netbeans est en anglais) et en choisissant les deux répertoires précédents. Il faut aussi rajouter les deux fichiers « lv_conf.h » et « lv_drv_conf.h ». Vous devez obtenir une arborescence du projet qui doit ressembler à celle-ci :

Cependant cela ne résout pas complètement le problème, il y un soucis d’include dans le fichier « lv_drivers/display/fbdev.h ». Il faut remplacer les lignes:
1 2 3 4 5 |
#ifdef LV_LVGL_H_INCLUDE_SIMPLE #include "lvgl.h" #else #include "lvgl/lvgl.h" #endif |
par
1 2 3 4 5 |
#ifdef LV_LVGL_H_INCLUDE_SIMPLE #include "lvgl.h" #else #include "../../lvgl/lvgl.h" #endif |
Relancez la compilation, cette fois-ci cela doit fonctionner. Vous obtenez un exécutable sur la RPi, pour moi ca sera dans le répertoire indiqué ci-dessous, à vous de l’adapter :
1 |
pi@pitft:~ $ cd .netbeans/remote/192.168.1.114/casimir-Linux-x86_64/home/olivier/NetBeansProjects/TestLittlevGL_Article/dist/Debug/GNU-Linux-x86/ |
Pour exécuter le code:
1 |
pi@pitft:~/.netbeans/remote/192.168.1.114/casimir-Linux-x86_64/home/olivier/NetBeansProjects/TestLittlevGL_Article/dist/Debug/GNU-Linux-x86 $ ./testlittlevgl_article |
Vous devez voir apparaître un écran qui ressemble à la capture ci-dessous. Tapez Ctrl+C pour quitter le programme.

Mise en oeuvre de la dalle tactile
On va maintenant modifier notre code pour mettre un « slider » et du coup tester le « tactile » avec la bibliothèque LittlevGL. Dans mon cas, j’ai choisi d’utiliser la bibliothèque « libinput » coté Linux pour la gestion de la dalle tactile. Mais avant cela il faut tester celle-ci sans programmation. Pour cela on va utiliser le logiciel evtest mais comme il est dit que ce logiciel est « déprécié » il faut passer au paquet « evemu-tools » et ces outils.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
pi@pitft:~ $ sudo apt install evemu-tools pi@pitft:~ $ sudo evemu-describe Available devices: /dev/input/event0: LITEON Technology USB Multimedia Keyboard /dev/input/event1: stmpe-ts Select the device event number [0-1]: 1 EVEMU 1.3 Kernel: 4.19.75-v7+ Input device name: "stmpe-ts" Input device ID: bus 0x18 vendor 0000 product 0000 version 0000 Supported events: Event type 0 (EV_SYN) Event code 0 (SYN_REPORT) Event code 1 (SYN_CONFIG) Event code 2 (SYN_MT_REPORT) Event code 3 (SYN_DROPPED) ... pi@pitft:~ $ sudo evemu-record /dev/input/event1 EVEMU 1.3 Kernel: 4.19.75-v7+ Input device name: "stmpe-ts" ... Event code 330 (BTN_TOUCH) Event type 3 (EV_ABS) Event code 0 (ABS_X) Value 0 Min 0 Max 4095 Fuzz 0 Flat 0 Resolution 0 Event code 1 (ABS_Y) Value 0 Min 0 Max 4095 Fuzz 0 Flat 0 Resolution 0 Event code 24 (ABS_PRESSURE) Value 0 Min 0 Max 255 Fuzz 0 Flat 0 Resolution 0 ... Waiting for events # E: 0.000001 0003 0000 3046 # EV_ABS / ABS_X 3046 E: 0.000001 0003 0001 2370 # EV_ABS / ABS_Y 2370 E: 0.000001 0003 0018 0178 # EV_ABS / ABS_PRESSURE 178 E: 0.000001 0001 014a 0001 # EV_KEY / BTN_TOUCH 1 E: 0.000001 0000 0000 0000 # ------------ SYN_REPORT (0) ---------- +0ms E: 0.006926 0003 0000 2980 # EV_ABS / ABS_X 2980 E: 0.006926 0003 0001 2381 # EV_ABS / ABS_Y 2381 E: 0.006926 0003 0018 0119 # EV_ABS / ABS_PRESSURE 119 E: 0.006926 0000 0000 0000 # ------------ SYN_REPORT (0) ---------- +6ms E: 0.013913 0003 0000 2870 # EV_ABS / ABS_X 2870 E: 0.013913 0003 0001 2398 # EV_ABS / ABS_Y 2398 E: 0.013913 0003 0018 0092 # EV_ABS / ABS_PRESSURE 92 E: 0.013913 0000 0000 0000 # ------------ SYN_REPORT (0) ---------- +7ms E: 0.020902 0003 0000 2877 # EV_ABS / ABS_X 2877 E: 0.020902 0003 0001 2409 # EV_ABS / ABS_Y 2409 |
La commande « evemu-describe » détecte deux périphériques d’entrée : un clavier USB en event0 et la dalle tactile en event1. Avec la commande « evemu-record », on peut visualiser les événements de la dalle tactile sur la console pour voir si celle-ci renvoie bien des données : c’est le cas ici. On peut remarquer aussi quelque chose d’intéressant : les « event code » 0 et 1 correspondent à la coordonnée absolue en X (ABS_X) et en Y (ABS_Y). Ces coordonnées évoluent entre 0 et 4095 soit le résultat d’une conversion sur 12 bits.
Il y a cependant un problème qui pourrait apparaître par la suite. Si on débranche le clavier USB et que l’on redémarre, le périphérique d’entrée de la dalle tactile va passer de « event1 » à « event0 ». Il faudrait pouvoir fixer le nom pour la dalle tactile. Ce problème est évoqué dans un article sur le site d’Adafruit : https://learn.adafruit.com/adafruit-pitft-28-inch-resistive-touchscreen-display-raspberry-pi et plus particulièrement sur cette partie : https://learn.adafruit.com/adafruit-pitft-28-inch-resistive-touchscreen-display-raspberry-pi/resistive-touchscreen-manual-install-calibrate . On va donc créer une règle udev pour que notre dalle tactile gérée par un stmpe-ts apparaisse toujours sous le nom « /dev/input/touchscreen » :
1 |
pi@pitft:~ $ sudo nano /etc/udev/rules.d/95-stmpe.rules |
On saisit la ligne suivante et on sauve:
1 |
SUBSYSTEM=="input", ATTRS{name}=="stmpe-ts", ENV{DEVNAME}=="<em>event</em>", SYMLINK+="input/touchscreen" |
Il faut redémarrer pour prendre en compte les changements. Puis on regarde si le lien symbolique est bien mis en place:
1 2 3 4 5 6 7 8 9 |
pi@pitft:~ $ ls -l /dev/input/ total 0 drwxr-xr-x 2 root root 60 oct. 23 18:10 by-id drwxr-xr-x 2 root root 80 oct. 23 18:10 by-path crw-rw---- 1 root input 13, 64 oct. 23 18:10 event0 crw-rw---- 1 root input 13, 65 oct. 23 18:10 event1 crw-rw---- 1 root input 13, 63 oct. 23 18:10 mice crw-rw---- 1 root input 13, 32 oct. 23 18:10 mouse0 lrwxrwxrwx 1 root root 6 oct. 23 18:10 touchscreen -> event1 |
C’est bon, on va pouvoir s’intéresser à la mise en oeuvre de la dalle tactile dans LittlevGL. pour cela il faut éditer le fichier « lv_drv_conf.h » et faire les modifications suivantes:
1 2 3 4 5 6 7 8 9 |
/*------------------------------------------------- Touchscreen as libinput interface (for Linux based systems) <em>------------------------------------------------</em>*/ #ifndef USE_LIBINPUT #define USE_LIBINPUT 0 #endif #if USE_LIBINPUT #define LIBINPUT_NAME "/dev/input/event1" #endif /<em>USE_LIBINPUT</em>/ |
par
1 2 3 4 5 6 7 8 9 |
/*------------------------------------------------- Touchscreen as libinput interface (for Linux based systems) <em>------------------------------------------------*</em>/ #ifndef USE_LIBINPUT #define USE_LIBINPUT 1 #endif #if USE_LIBINPUT #define LIBINPUT_NAME "/dev/input/touchscreen" #endif /<em>USE_LIBINPUT</em>/ |
Modifiez alors le code précédent pour mettre en place un slider et la gestion d’événements sur celui-ci:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 |
#include "lvgl/lvgl.h" #include "lv_drivers/display/fbdev.h" #include "lv_drivers/indev/libinput_drv.h" #include <unistd.h> #include <cstdio> #define DISP_BUF_SIZE (80*LV_HOR_RES_MAX) static void my_event_cb_slider(lv_obj_t * obj, lv_event_t event) { switch(event) { case LV_EVENT_PRESSED: printf("Pressed\n"); break; case LV_EVENT_SHORT_CLICKED: printf("Short clicked\n"); break; case LV_EVENT_CLICKED: printf("Clicked\n"); break; case LV_EVENT_LONG_PRESSED: printf("Long press\n"); break; case LV_EVENT_LONG_PRESSED_REPEAT: printf("Long press repeat\n"); break; case LV_EVENT_RELEASED: printf("Released\n"); break; case LV_EVENT_VALUE_CHANGED: printf("Slider bouge\n"); break; } /*Etc.*/ } int main(void) { /*LittlevGL init*/ lv_init(); /*Linux frame buffer device init*/ fbdev_init(); /*Initialisation de la gestion des péripheriques d'entrees par la bibliothèque libinput */ libinput_init(); /*A small buffer for LittlevGL to draw the screen's content*/ static lv_color_t buf[DISP_BUF_SIZE]; /*Initialize a descriptor for the buffer*/ static lv_disp_buf_t disp_buf; lv_disp_buf_init(&disp_buf, buf, NULL, DISP_BUF_SIZE); /*Initialize and register a display driver*/ lv_disp_drv_t disp_drv; lv_disp_drv_init(&disp_drv); disp_drv.buffer = &disp_buf; disp_drv.flush_cb = fbdev_flush; lv_disp_drv_register(&disp_drv); /*Initialisation du touchscreen*/ lv_indev_drv_t indev_drv; lv_indev_drv_init(&indev_drv); /*Basic initialization*/ indev_drv.type = LV_INDEV_TYPE_POINTER; indev_drv.read_cb = libinput_read; //evdev_read; /*See below.*/ /*Register the driver in LittlevGL and save the created input device object*/ lv_indev_t * my_indev = lv_indev_drv_register(&indev_drv); /*Create a "Hello world!" label*/ lv_obj_t * label = lv_label_create(lv_scr_act(), NULL); lv_label_set_text(label, "Hello world!"); lv_obj_align(label, NULL, LV_ALIGN_CENTER, 0, 0); // Ajout Olivier Test Slider lv_obj_t* slider = lv_slider_create(lv_scr_act(), NULL); lv_obj_set_x(slider,10); lv_obj_set_y(slider,10); lv_obj_set_size(slider, 220, 30); lv_slider_set_knob_in(slider, true); // appel de la fonction my_event_cb_slider sur un evenement touchscreen lv_obj_set_event_cb(slider, my_event_cb_slider); /*Handle LitlevGL tasks (tickless mode)*/ while(1) { lv_tick_inc(5); lv_task_handler(); usleep(5000); } return 0; } |
Le code précédent ne compile pas. Il y a le même soucis d’include que précédemment dans le fichier « lv_drivers/indev/libinput_drv.h ». Il faut remplacer les lignes:
1 2 3 4 5 |
#ifdef LV_LVGL_H_INCLUDE_SIMPLE #include "lvgl.h" #else #include "lvgl/lvgl.h" #endif |
par
1 2 3 4 5 |
#ifdef LV_LVGL_H_INCLUDE_SIMPLE #include "lvgl.h" #else #include "../../lvgl/lvgl.h" #endif |
Au moment de la compilation, la bibliothèque « libinput » n’est pas trouvé sur le raspberryPi. Il faut donc l’installer avec la commande suivante:
1 |
pi@pitft:~ $ sudo apt install libinput-dev |
Au niveau des options de compilation du projet dans Netbeans, il faut rajouter l’option « -linput » : clic droit sur le nom du projet puis choix « properties » puis rajouter dans « build » option « linker » dans le champ « Additional options » mettre « -linput » (la première lettre est un L minuscule). Relancez la compilation cette fois ci ça doit fonctionner et vous devez obtenir un exécutable. Lancez-le !
Le slider doit apparaître en haut de l’écran au dessus du label « hello world ». Lorsque vous essayez de le bouger avec votre doigt rien ne se passe ! Faites glisser votre doigt sur le coté droit de l’écran et vous verrez bouger le slider et les événements s’afficher dans la console.
Donc ça fonctionne presque correctement, les axes X et Y de la dalle tactile ne correspondent pas aux axes X et Y de l’écran !
Première solution : mettre l’écran en mode portrait : modifiez la ligne qui concerne l’écran pitft dans le fichier /boot/config.txt comme suit: dtoverlay=pitft28-resistive,rotate=0 puis modifiez les valeurs dans le fichier « lv_conf.h » en échangeant les valeurs X et Y de l’écran pour obtenir ceci:
1 2 3 |
/* Maximal horizontal and vertical resolution to support by the library.*/ define LV_HOR_RES_MAX (240) define LV_VER_RES_MAX (320) |
Redémarrez puis lancez l’exécutable : ça fonctionne en mode portrait.
Deuxième solution : Cependant si vous souhaitez conserver le mode paysage (pas de paramètre supplémentaire sur la ligne dtoverlay=pitft28-resistive) ca va être un plus dur. Il faut configurer une matrice de transformation de coordonnées au niveau de la bibliothèque libinput. Après des recherches pénibles je suis arrivé sur cette page : https://wayland.freedesktop.org/libinput/doc/latest/api/group__config.html#ga09a798f58cc601edd2797780096e9804 . Elle présente comment manipuler les coordonnées renvoyées par la dalle tactile pour les adapter à l’orientation de l’écran. Par défaut l’écran a en fait une rotation de 90°, je vais donc prendre la matrice de transformation qui correspond à cette rotation : [0 -1 1] et [1 0 0]. Pour que cette transformation soit effective, il faut modifier la fonction « libinput_set_file » du fichier « lv_drivers/indev/libinput.c » en rajoutant ce qui suit avant la ligne « libinput_button = LV_INDEV_STATE_REL; » :
1 2 3 4 |
// Ajout Olivier DARTOIS // rotation de 90° const float matrix[6] = {0., -1., 1., 1., 0., 0.}; libinput_device_config_calibration_set_matrix (libinput_device, matrix); |
Recompilez et testez, votre slider doit maintenant se déplacer correctement avec votre écran en orientation paysage. La petite photo qui va bien ci-dessous mais elle ne prouve rien il faudrait une vidéo 🙂

Et la suite…
Cet article ne parle pas de la mise en oeuvre des widgets, les exemples et la documentation de LittlevGL sont là pour ça. Cet article s’est attaché à faire fonctionner la bibliothèque LittlevGL sur un écran TFT avec une dalle tactile. Les explications données ici doivent être valables pour n’importe quel écran et dalle tactile du moment qu’ils soient supportés par le noyau Linux.
En vous souhaitant un bon développement avec cette magnifique bibliothèque…