Test d’un écran couleur 3,5″

mario

L’écran intégré dans notre prototype actuel a une taille de 2,8″, et il faut reconnaître qu’on commence à se sentir à l’étroit ! Nous l’avions choisi pour sa très faible consommation, mais le fait d’être en noir et blanc est également assez limitant pour l’intégration des interfaces graphiques que nous envisageons d’utiliser.

Aujourd’hui donc, on test un écran couleur 3,5″ avec une résolution de 320×240 ! Nous avons choisi ce modèle : http://www.buydisplay.com/default/3-5-inch-tft-lcd-color-module-in-320×240-touch-screen-lq035nc111

écran couleur

La consommation sera clairement plus élevée qu’avec l’ancien écran, mais le gain en confort d’utilisation en vaut la peine !

Notre premier écran est cablé sur le bus SPI de notre board, et nous avions nous même codé le driver linux.  Pour l’écran couleur, nous ne pourrons pas réutiliser notre travail car l’interface hardware  est différente, mais c’est l’occasion de voir comment cela fonctionne !

Types d’écran TFT

On trouve deux catégories de module TFT couleurs :

Les écrans intelligents

C’est le cas de notre écran. ll intègre un contrôleur qui se charge de stocker dans une mémoire interne l’image qui doit être affichée à l’écran. Le contrôleur de notre écran est un HX8238-A. La technologie TFT ne permet pas de conserver une image à l’écran pendant une longue période, il faut constamment rafraîchir l’écran, à une fréquence de 60Hz par exemple, pour ne pas avoir d’impression de scintillement de l’affichage. Le rôle du contrôleur est donc de servir de tampon entre le périphérique qui génère les images à afficher (ici notre processeur), et la dalle TFT de l’écran qui doit être rafraîchie régulièrement, même si l’image ne change pas. Il serait tout à fait possible de se passer de contrôleur intégré, mais il faudrait alors que le processeur envoie régulièrement l’image vers l’écran, ce qui est coûteux en bande passante, et potentiellement en temps CPU s’il n’y a pas de gestion hardware du rafraîchissement.

La bande passante consommée sur le bus CPU – Dalle TFT, si on devait utiliser un écran sans contrôleur intégré, se calcul de la façon suivante :

Résolution en X * Résolution en Y * Profondeur de couleur * Fréquence de rafraîchissement = bande passante consommée.

Pour notre écran  cela donne  : 240 * 320 * 24 * 60  = 105 Mbit/s

C’est autre chose que les 2Mbit/s de notre bus SPI qui alimentait l’écran noir et blanc !

Sans gestion hardware du rafraîchissement d’écran TFT sur le processeur, ca ne serait pas jouable de le gérer logiciellement, car très certainement trop consommateur en ressources. Le contrôleur intégré permet au processeur de n’envoyer l’image que lorsque change, on gagne donc beaucoup de temps CPU !

Un autre avantage des écrans « intelligents » (à contrôleur intégré donc), est que le contrôleur propose en général différentes interfaces pour recevoir les données, SPI/Parallèle/MCU/… au niveau de l’écran.

Les écrans « idiots » ou « dumb »

Ces écrans n’ont tout simplement pas de contrôleur intégré, il faut donc que le périphérique qui pilote l’écran soit prévu pour gérer le rafraîchissement régulier de la dalle. De plus, ces écrans n’offrent qu’une interface : un bus parallèle pour coder la valeur des pixels (24 pins si l’écran gère une profondeur de couleur de 24bits) + 3 signaux de contrôle : VSYNC, HSYNC, DOTCLOCK.

L’interface de ces écrans peut être nommée RGB ou Dotclock.

Comment piloter notre écran ?

Interface avec le processeur

Notre écran possède donc un contrôleur intégré, et nous aimerions pouvoir nous en servir de façon standard sous linux. En commençant par regarder la datasheet de notre processeur, le iMX.233, on constate (http://cache.freescale.com/files/dsp/doc/ref_manual/IMX23RM.pdf page 52 du PDF ):

  • Supports 24-bit full color parallel RGB (DOTCK) mode. Able to drive up to VGA (640×480) full color displays at refresh rates up to 60Hz.
  • Supports full 24-bit system mode (8080/6080/VSYNC/WSYNC).

Le iMX.233 possède une gestion hardware des écrans TFT, et peut piloter un écran directement en RGB, c’est à dire que nous pourrions utiliser un écran dumb. Cela serait même l’idéal car on imagine qu’un écran dumb nous coutera moins cher car  il n’émbarque pas de contrôleur intégré. Nous n’avons pourtant pas trouvé beaucoup de petits écrans TFT sans contrôleur. Sûrement par ce que les petits écrans sont plus souvent utilisés pour être cablés sur des microcontrôleurs, qui eux n’ont pas de gestion hardware de l’interface RGB.

Utilisation sous linux

Maintenant que nous savons que le processeur supporte en hardware les interfaces disponibles sur notre écran, voyons maintenant si le support est déjà codé sous Linux. Nous constatons que certains ont déjà réussi à utiliser un écran couleur avec un iMX.233 directement en RGB : https://www.olimex.com/forum/index.php?topic=995.0

Nous utilisons actuellement un noyau Linux 3.15, voyons voir si un module est disponible dans les sources pour le supporte de l’interface LCDIF du iMX.233. On trouve le module suivant :

  • drivers/video/mxsfb.c

Et dans les premières lignes du modules :

/**
 * @file
 * @brief LCDIF driver for i.MX23 and i.MX28
 *
 * The LCDIF support four modes of operation
 * - MPU interface (to drive smart displays) -> not supported yet
 * - VSYNC interface (like MPU interface plus Vsync) -> not supported yet
 * - Dotclock interface (to drive LC displays with RGB data and sync signals)
 * - DVI (to drive ITU-R BT656)  -> not supported yet
 *
 * This driver depends on a correct setup of the pins used for this purpose
 * (platform specific).
...

Parfait ! Un module existe déjà, et même s’il ne supporte que l’interface DOTCLOCK, c’est celle que nous préférons utiliser, en prévision d’un passage futur sur un écran dumb.

Le driver utilise device-tree pour recupérer les paramêtres de l’écran (comme la résolution, la profondeur de couleur, la fréquence de rafraichissement…), nous ne devrions donc pas à avoir besoin de toucher au code du module, mais seulement aux fichiers dts (qui contient les caractéristiques de notre board), ou au fichier .dtsi (qui contient les caractéristiques du processeur) :

  • arch/arm/boot/dts/imx23.dtsi
  • arch/arm/boot/dts/imx23-olinuxino.dts (nous utilisons comme board de référence une olinuxino)

Voici le diff qui correspond à l’ajout des caractéristiques de notre écran dans le .dts :

diff --git a/arch/arm/boot/dts/imx23.dtsi b/arch/arm/boot/dts/imx23.dtsi
index c96ceae..110520d 100644
--- a/arch/arm/boot/dts/imx23.dtsi
+++ b/arch/arm/boot/dts/imx23.dtsi
@@ -162,8 +162,8 @@
                                auart0_2pins_a: auart0-2pins@0 {
                                        reg = <0>;
                                        fsl,pinmux-ids = <
-                                               MX23_PAD_I2C_SCL__AUART1_TX
-                                               MX23_PAD_I2C_SDA__AUART1_RX
+                                               MX23_PAD_AUART1_TX__AUART1_TX
+                                               MX23_PAD_AUART1_RX__AUART1_RX
                                        >;
                                        fsl,drive-strength = <MXS_DRIVE_4mA>;
                                        fsl,voltage = <MXS_VOLTAGE_HIGH>;
@@ -269,22 +269,20 @@
                                                MX23_PAD_LCD_D05__LCD_D05
                                                MX23_PAD_LCD_D06__LCD_D06
                                                MX23_PAD_LCD_D07__LCD_D07
-                                               MX23_PAD_LCD_D08__LCD_D08
-                                               MX23_PAD_LCD_D09__LCD_D09
-                                               MX23_PAD_LCD_D10__LCD_D10
-                                               MX23_PAD_LCD_D11__LCD_D11
-                                               MX23_PAD_LCD_D12__LCD_D12
-                                               MX23_PAD_LCD_D13__LCD_D13
-                                               MX23_PAD_LCD_D14__LCD_D14
-                                               MX23_PAD_LCD_D15__LCD_D15
-                                               MX23_PAD_LCD_D16__LCD_D16
-                                               MX23_PAD_LCD_D17__LCD_D17
+                                               MX23_PAD_GPMI_D00__LCD_D8
+                                               MX23_PAD_GPMI_D01__LCD_D9
+                                               MX23_PAD_GPMI_D02__LCD_D10
+                                               MX23_PAD_GPMI_D03__LCD_D11
+                                               MX23_PAD_GPMI_D04__LCD_D12
+                                               MX23_PAD_GPMI_D05__LCD_D13
+                                               MX23_PAD_GPMI_D06__LCD_D14
+                                               MX23_PAD_GPMI_D07__LCD_D15
+                                               MX23_PAD_GPMI_CLE__LCD_D16
+                                               MX23_PAD_GPMI_ALE__LCD_D17
                                                MX23_PAD_GPMI_D08__LCD_D18
                                                MX23_PAD_GPMI_D09__LCD_D19
                                                MX23_PAD_GPMI_D10__LCD_D20
                                                MX23_PAD_GPMI_D11__LCD_D21
-                                               MX23_PAD_GPMI_D12__LCD_D22
-                                               MX23_PAD_GPMI_D13__LCD_D23
                                                MX23_PAD_LCD_DOTCK__LCD_DOTCK
                                                MX23_PAD_LCD_ENABLE__LCD_ENABLE
                                                MX23_PAD_LCD_HSYNC__LCD_HSYNC
@@ -362,7 +360,35 @@
                                reg = <0x80030000 2000>;
                                interrupts = <46 45>;
                                clocks = <&clks 38>;
-                               status = "disabled";
+
+                                pinctrl-names = "default";
+                                pinctrl-0 = <&lcdif_24bit_pins_a>;
+                                display = <&display>;
+                                status = "okay";
+
+                                display: display {
+                                        bits-per-pixel = <16>;
+                                        bus-width = <18>;
+
+                                        display-timings {
+                                                native-mode = <&timing0>;
+                                                timing0: timing0 {
+                                                        clock-frequency = <25000000>;
+                                                        hactive = <320>;
+                                                        vactive = <240>;
+                                                        hback-porch = <(-29)>;
+                                                        hfront-porch = <35>;
+                                                        vback-porch = <16>;
+                                                        vfront-porch = <10>;
+                                                        hsync-len = <96>;
+                                                        vsync-len = <2>;
+                                                        hsync-active = <0>;
+                                                        vsync-active = <0>;
+                                                        de-active = <1>;
+                                                        pixelclk-active = <0>;
+                                                };
+                                        };
+                                };
                        };
 
                        ssp1: ssp@80034000 {

 

Quelques précisions sur ce diff :

  • Notre écran supporte une profondeur de couleur de 24bits, mais nous allons l’utiliser en mode 18 bits pour le moment (6 bits pour chaque couleur). Nous faisons nos tests sur une olinuxino mini et le package du iMX.233 utilisé sur cette board est LQFN et pas BGA, contrairement à notre board. La version  LQFN du iMX.233 n’a pas assez de pin pour gérer le mode 24bits, seulement 18bits. La version BGA, elle, gère le 24bits.
  • La définition des pins utilisés pour l’écran se trouve dans le fichier arch/arm/boot/dts/imx23-pinfunc.h

Après avoir ajouté les caractéristiques de l’écran dans le fichier .dtsi, on le régénère :

make imx23-olinuxino.dtb

puis on le copie à la place de l’ancien sur la carte SD de notre olinuxino mini.

Il ne reste plus qu’à sélectionner le module dans la configuration du noyau et à le compiler :

calc@dc8407508e62:~/calculator/system/linux$ make menuconfig
# Device Drivers -> Graphics support -> Support for frame buffer devices -> MXS LCD framebuffer support
calc@dc8407508e62:~/calculator/system/linux$ make modules
calc@dc8407508e62:~/calculator/system/linux$ ls drivers/video/mxsfb.ko
drivers/video/mxsfb.ko

Puis à le insmod sur notre board de test  :

root@(none):~# ls /dev/fb0
ls: cannot access /dev/fb0: No such file or directory
root@(none):~# insmod fb/mxsfb.ko
[   55.020000] 80030000.lcdif supply lcd not found, using dummy regulator
[   55.050000] Console: switching to colour frame buffer device 40x30
[   55.070000] mxsfb 80030000.lcdif: initialized
root@(none):~# ls /dev/fb0
/dev/fb0
root@(none):~# fbset

mode "320x240-221"
    # D: 25.000 MHz, H: 59.242 kHz, V: 221.051 Hz
    geometry 320 240 320 240 16
    timings 40000 -29 35 16 10 96 2
    rgba 5/11,6/5,5/0,0/0
endmode

root@(none):~#

 

Et voilà ! Il ne reste plus qu’à utiliser notre écran ! On peut maintenant lancer Xorg ou directement des applications en framebuffer.

Une réflexion sur “ Test d’un écran couleur 3,5″ ”

  1. Super !! Vive les écrans couleurs et la « haute résolution » sur calculatrice !! Avec un si bon écran vous allez pouvoir faire une interface géniale, vous pensez la faire ressembler à quoi (Ti Nspire cx cas, HP Prime …) ?
    Et beau boulot pour le 2nd prototype !! Il est vraiment très réussi ;) Pour quand des images de calcul formel sur ces super joujoux ?

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *


*

Vous pouvez utiliser ces balises et attributs HTML : <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>