SPI driven QVGA TFT

The TFT from MikroElektronika http://www.mikroe.com/eng/products/view/474/tft-proto-board/ come on a pcb with a easy to use pinout.

MikroElektronika has changed the Display !!

MicroElektronika has changed the type of display used in her product. The new display has a different controller and the lib has be changed to support this.

You find the new lib here : http://mbed.org/users/dreschpe/code/SPI_TFT_ILI9341/ There is also a small test program : http://mbed.org/users/dreschpe/code/TFT_Test_ILI9341/

Peter

/media/uploads/dreschpe/tft_proto_01.jpg

Connecting to the mbed

The board use 3.3V so we can attach it direct to the mbed. The backlite LED need a resistor to limit the current. I use two 10R resistors parallel to get 5R driven by 3.3V.

The interface can be driven in 16 bit,8 bit, 18 bit, 9 bit or SPI mode. Because I don't want to spend all mbed IOs to the display I use the SPI mode. The IMx-pins have to set to IM0,IM1,IM3 : GND, IM2 : 3.3V. The RST pin is connected to reset, RS and FMARK are not used.

For SPI mode we need only the tree SPI signals, a cs and a reset signal. 5 pins at all. SPI is serial and we have to transfer 320 * 240 * 16 = 1228800 bits to the display to fill it up. Will it be to slow ? No ! We can drive the SPI to display with 48Mhz clock speed ! 50Mhz is the limit, but the mbed is running at 96Mhz and we can divide this clock by two.

The lib supports also the new Freescale KL25Z board. At the moment it is working at 10MHz SPI clock.

/media/uploads/dreschpe/tft.png

Software: SPI_TFT library

latest Version :

DMA use

The lib use a io pin to generate the cs signal again. The automatic spi cs could make problems when interrupted by interrupts or RTOS. My tests with the RTOS are stable.

The cls() is six times faster !

Bugfix : the bmp from filesystem is working again http://mbed.org/users/dreschpe/code/SPI_TFT/

If you use a LPC11U24 the DMA is not used If you use a KL25Z the DMA is not used

If you want to switch off DMA use, comment out the NO_DMA define at top of spi_tft.h file

How to get nice looking fonts ?

To print characters to a graphic screen we need a font. To code a font by paper is ok for a small lcd, but for a 320*240 pixel display we need bigger fonts. A 12*12 pixel font is readable, but a lot of work to construct.

Fonts can be made with the GLCD Font Creator also from http://www.mikroe.com .

With this program you can load a window font and convert it into a c-array. To use this Font with my lib you have to add 4 parameter at the beginning of the font array. - the number of byte / char - the vertial size in pixel - the horizontal size in pixel - the number of byte per vertical line (it is vertical size / 8 ) You also have to change the array to char[]. After that you can switch between different fonts with set_font(unsigned char* font); The horizontal size of each character is also stored in the font. It look better if you use bigger fonts or italic. The letter M is wider than a l.

Here are some Fonts from me : http://mbed.org/users/dreschpe/code/TFT_fonts/

The small made for the mbed lab board : http://mbed.org/users/dreschpe/code/LCD_fonts/

And from Peter Holzleitner : http://mbed.org/users/pholzleitner/code/SourceCodePro31-SB/

Text commands :

You can use the claim() function to redirect the output to stdout or stderr to the TFT. After claim(stdout) you can simply use the printf function to print to the TFT.

  • locate(x,y); function is used to setup the cursor position. x,y are the pixel position. This was changed from row,column in older lib !

There are two parameter to setup the color of the text :

  • background(color);
  • foreground(color); All color are 16bit: R5 G6 B5.
  • set_orientation(); This command select one of the 4 directions to use the display. This command is also working on the graphical commands.

Graphic commands :

  • cls(); Fill the screen with background color
  • pixel(x,y,color); set a single pixel at x,y with color
  • line(x0,y0,x1,y1,color); draw a line from x0,y0 to x1,y1 with color
  • rect(x0,y0,x1,y1,color); draw a rectangle x0,y0 to x1,y1 with color
  • fillrect(x0,y0,x1,y1,color); draw a filled rectangle
  • circle( x0,y0,radius ,color); draw a circle around x0,y0 with radius
  • fillcircle(x0,y0,radius ,color); draw a filled circle around x0,y0 with radius
  • Bitmap(x0,y0,w,h,*bitmap); paint a bitmap with width w and high h starting at x0,y0 (upper left corner)
  • BMP_16(x0,y0,*bmp); paint a bmp file out of the internal drive

How to transfer a grafic to the mbed ?

The hard way - but fast to load :

Load from mbed flash. To construct a bitmap array we can use gimp. http://www.gimp.org/ Load a image (edit and resize) and save it as BMP. You have to select the option 16 bit R5 G6 B5 !

To convert this file into a c-array you can use the hex-editor winhex. (http://www.x-ways.net/winhex/index-m.html) The eval version can handle the small files. We don`t need the bmp header. Mark the data starting at offset 0x46 to the end of file. Use "edit -> copy block -> C Source" to export this data as C array. Paste the data into a C file into the mbed compiler. The editor will generate a array of char[]. To use 16 bit DMA on this we have to put a __align(2) in front of the definition. To put it into Flash we change it to static const unsigned char bmp[]{...}

__align(2)
static const unsigned char bmp[]{
      0xCB, 0x5A, 0x5C, 0xE7,....

};

The easy way - but slower to load:

With the BMP_16 command we can load a picture out of the internal drive to the display.

  • BMP_16(x0,y0,"test.bmp"); paint test.bmp out of the internal drive to x0, y0

simply copy test.bmp to mbed usb drive - saved with the options 16 bit R5 G6 B5 and load it. The KL25Z board does not support the local filesystem.

The demo code : (It is difficult to make pictures from the screen - it looks better)

 // example to test the TFT Display
 // Thanks to the GraphicsDisplay and TextDisplay classes from 

#include "stdio.h"
#include "mbed.h"
#include "SPI_TFT.h"
#include "string"
#include "Arial12x12.h"
#include "Arial24x23.h"
#include "Arial28x28.h"
#include "font_big.h"

extern unsigned char p1[];  // the mbed logo

// the TFT is connected to SPI pin 5-7 
SPI_TFT TFT(p5, p6, p7, p8, p15,"TFT"); // mosi, miso, sclk, cs, reset

// possible setup for the KL25Z board :
//SPI_TFT TFT(PTD2, PTD3, PTD1, PTD0, PTD5,"TFT"); // mosi, miso, sclk, cs, reset

int main() {
    int i;
    TFT.claim(stdout);      // send stdout to the TFT display 
    //TFT.claim(stderr);      // send stderr to the TFT display

    TFT.background(Black);    // set background to black
    TFT.foreground(White);    // set chars to white
    TFT.cls();                // clear the screen
    TFT.set_font((unsigned char*) Arial12x12);  // select the font
      
    // first show the 4 directions  
    TFT.set_orientation(0);
    TFT.locate(0,0);
    printf("  Hello Mbed 0");
    TFT.set_orientation(1);
    TFT.locate(0,0);
    printf("  Hello Mbed 1");
    TFT.set_orientation(2);
    TFT.locate(0,0);
    printf("  Hello Mbed 2");
    TFT.set_orientation(3);
    TFT.locate(0,0);
    printf("  Hello Mbed 3");
    TFT.set_orientation(1);
    TFT.set_font((unsigned char*) Arial24x23);
    TFT.locate(48,115);
    TFT.printf("TFT orientation");
       
    wait(5);        // wait two seconds 

/media/uploads/dreschpe/orientation.jpg

 // draw some graphics 
    TFT.cls();          
    TFT.set_orientation(1);
    TFT.set_font((unsigned char*) Arial24x23);
    TFT.locate(120,115);
    TFT.printf("Graphic");
     
    TFT.line(0,0,100,200,Green);
    TFT.rect(100,50,150,100,Red);
    TFT.fillrect(180,25,220,70,Blue);
    TFT.circle(80,150,33,White);

/media/uploads/dreschpe/graphic.jpg

 wait(5);        // wait two seconds
    
    // bigger text
    TFT.foreground(White);
    TFT.background(Blue);
    TFT.cls();
    TFT.set_font((unsigned char*) Arial24x23);
    TFT.locate(0,0);
    TFT.printf("Different Fonts :");
    
    TFT.set_font((unsigned char*) Neu42x35);
    TFT.locate(0,50);
    TFT.printf("Hello Mbed 1");
    TFT.set_font((unsigned char*) Arial24x23);
    TFT.locate(50,100);
    TFT.printf("Hello Mbed 2");
    TFT.set_font((unsigned char*) Arial12x12);
    TFT.locate(55,150);
    TFT.printf("Hello Mbed 3");

/media/uploads/dreschpe/fonts.jpg

wait(5);
  
    // mbed logo  
    TFT.set_orientation(1);
    TFT.background(Black);
    TFT.cls();
    TFT.Bitmap(90,90,172,55,p1);
}

/media/uploads/dreschpe/logo.jpg

The touchscreen

The Touch_tft class is derived from the SPI_TFT class.

I add the support for the touchscreen :

http://mbed.org/users/dreschpe/notebook/touchscreen/

http://mbed.org/users/dreschpe/libraries/Touch_tft/lx1972

/media/uploads/dreschpe/_scaled_touch.jpg

A Demo to use the touch function : http://mbed.org/users/dreschpe/notebook/micro-paint/