Lib for the new LCD Display with ILI9341 controller

Dependents:   TFT_Test_ILI9341 touch_piirto TFT_banggood TFT_Test_ILI9341-a-fish ... more

Lib for 320*240 Pixel Color LCD with ILI9341 controller. Based on MI0283QT-9 datasheet. The lib is based on the http://mbed.org/cookbook/SPI-driven-QVGA-TFT code for the older LCD board.

The lib is using the 4 line serial data interface. The IM pins have to be set to 1110 (IM3-IM0) to use this mode. It use the SPI hardware.

I have started to speed up the lib with using DMA and direct SPI programming. To do this I have to split the code for the different platforms. To prevent unreadable code with a lot of #ifdef... I have create a new file. The #ifdef definition around is switching between the platforms. I will add the other Nucleo platforms. If you want to support others - see ..._NUCLEO.cpp , port and send me the code to add.

Display 1

If you use the TFT Proto from MikroElektronika http://www.mikroe.com/eng/products/view/474/tft-proto-board/ you have to connect : /media/uploads/dreschpe/tft_proto.png

MBEDDisplay
+ 3,3V3,3V
GNDGND
mosiSDI
misoSDO
sckRS
csCS
resetRST
dcWR/SCL
GNDIM0
+3,3VIM1 IM2 IM3
GNDDB0 - DB17
GNDRD

The backlite LED need a resistor to limit the current. You can use two 10R resistors parallel to get 5R driven by 3.3V.

Display 2

Watterott is also selling a ILI9341 based QVGA TFT : http://www.watterott.com/de/MI0283QT-2-Adapter

Unfortunately this adapter is set to 9 bit SPI mode via the mode pins IM0-IM3. If you want to patch this - like I have done - you have to desolder the TFT from the pcb to cut some traces. This is a flexible print. Only for people with soldering skills ! You also have to get access to pin 36 for the dc signal. Cut the GND connection. You can use the level converter used for the LCD_LED signal. Mosfet Q1 can be driven with a logic signal without converter. Watterott will change this in a future revision.

/media/uploads/dreschpe/mi0283qt_v12_patch.pdf

Display 3

There are inexpensive displays from china. You can get them at: http://www.banggood.com/2_2-Inch-Serial-TFT-SPI-LCD-Screen-Module-HD-240-X-320-5110-Compatible-p-912854.html The board has also a SD card connector at the backside, but no touch.

/media/uploads/dreschpe/tft3_1.jpg /media/uploads/dreschpe/tft3_2.jpg

The board can be used without modification. Connect VCC with 5V USB out. There is a voltage regulator on board. To use the SD card simply import the SDFileSystem and connect it to the second SPI.

Fonts

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.

Graphics

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 or a SD-card

How to transfer a grafic to the mbed ?

The hard way - but fast to load :

Load from mbed flash. It consume a lot of flash memory. To construct a bitmap array we can use gimp. http://www.gimp.org/ Load a image (edit and resize) and export 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 or a SD-card to the display.

  • BMP_16(x0,y0,"/local/test.bmp"); paint test.bmp out of the internal drive to x0, y0
  • BMP_16(x0,y0,"/sd/test.bmp"); paint test.bmp out of a external SD-card to x0, y0

simply copy test.bmp to the mbed usb drive or the SD-card. The bmp has to be saved with the options 16 bit R5 G6 B5 ! You can use the program gimp to convert pictures into the 16 bit bmp format.

sample code

http://mbed.org/users/dreschpe/code/TFT_Test_ILI9341/

// example to test the TFT Display
// Thanks to the GraphicsDisplay and TextDisplay classes
// test2.bmp has to be on the mbed file system

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

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

DigitalOut LCD_LED(p21); // the Watterott display has a backlight switch
DigitalOut CS_Touch(p15); // disable the touch controller on the Watterott display

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

int main()
{
    int i;
    LCD_LED = 1;  // backlight on
    CS_Touch = 1; 
   
    TFT.claim(stdout);      // send stdout to the TFT display
    //TFT.claim(stderr);      // send stderr to the TFT display
    TFT.set_orientation(1);
    TFT.background(Black);    // set background to black
    TFT.foreground(White);    // set chars to white
    TFT.cls();                // clear the screen

    //first show the 4 directions
    TFT.set_orientation(0);
    TFT.background(Black);
    TFT.cls();

    TFT.set_font((unsigned char*) Arial12x12);
    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(50,100);
    TFT.printf("TFT orientation");

/media/uploads/dreschpe/orient.jpg

// draw some graphics
    TFT.cls();
    TFT.set_font((unsigned char*) Arial24x23);
    TFT.locate(100,100);
    TFT.printf("Graphic");

    TFT.line(0,0,100,0,Green);
    TFT.line(0,0,0,200,Green);
    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);
    TFT.fillcircle(160,190,20,Yellow);

    double s;

    for (i=0; i<320; i++) {
        s =20 * sin((long double) i / 10 );
        TFT.pixel(i,100 + (int)s ,Red);
    }

/media/uploads/dreschpe/grafik.jpg

   // 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,30);
    TFT.printf("Hello Mbed 1");
    TFT.set_font((unsigned char*) Arial24x23);
    TFT.locate(20,80);
    TFT.printf("Hello Mbed 2");
    TFT.set_font((unsigned char*) Arial12x12);
    TFT.locate(35,120);
    TFT.printf("Hello Mbed 3");

/media/uploads/dreschpe/fonts2.jpg

    // mbed logo from flash
    // defined in graphics.c
    //__align(4)
    //unsigned char p1[18920] = {
    //0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, ....
    // 
    TFT.background(Black);
    TFT.cls();

    TFT.locate(10,10);
    TFT.printf("Graphic from Flash");

    TFT.Bitmap(90,90,172,55,p1);

/media/uploads/dreschpe/mbed.jpg

  
  #include "SDFileSystem.h"
  // connect a sd-card to the second spi or use the local filesystem of the LPC   
  SDFileSystem sd(p11, p12, p13, p14, "sd"); // mosi,miso,sck,cs
  TFT.cls();
  TFT.locate(10,110);
  TFT.printf("Graphic from external SD-card");
  int err = TFT.BMP_16(1,140,"/sd/test.bmp");  // load test.bmp from external SD-card
  TFT.locate(10,120);
  if (err != 1) TFT.printf(" - Err: %d",err);

/media/uploads/dreschpe/bmp16.jpg

Committer:
dreschpe
Date:
Sun Jan 26 16:58:45 2014 +0000
Revision:
6:fe07ae8329f7
Parent:
5:55aed13f2630
Child:
7:4c30bea883bc
Change the bmp16 interface to also use SD-cards to load pictures.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
dreschpe 0:da1bf437cbc1 1 /* mbed library for 240*320 pixel display TFT based on ILI9341 LCD Controller
dreschpe 0:da1bf437cbc1 2 * Copyright (c) 2013 Peter Drescher - DC2PD
dreschpe 0:da1bf437cbc1 3 *
dreschpe 0:da1bf437cbc1 4 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
dreschpe 0:da1bf437cbc1 5 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
dreschpe 0:da1bf437cbc1 6 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
dreschpe 0:da1bf437cbc1 7 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
dreschpe 0:da1bf437cbc1 8 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
dreschpe 0:da1bf437cbc1 9 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
dreschpe 0:da1bf437cbc1 10 * THE SOFTWARE.
dreschpe 0:da1bf437cbc1 11 */
dreschpe 0:da1bf437cbc1 12
dreschpe 0:da1bf437cbc1 13 // 12.06.13 fork from SPI_TFT code because controller is different ...
dreschpe 2:0a16083193a4 14 // 14.07.13 Test with real display and bugfix
dreschpe 4:f018e272220b 15 // 18.10.13 Better Circle function from Michael Ammann
dreschpe 5:55aed13f2630 16 // 22.10.13 Fixes for Kinetis Board - 8 bit spi
dreschpe 6:fe07ae8329f7 17 // 26.01.14 Change interface for BMP_16 to also use SD-cards
dreschpe 0:da1bf437cbc1 18
dreschpe 0:da1bf437cbc1 19 #include "SPI_TFT_ILI9341.h"
dreschpe 0:da1bf437cbc1 20 #include "mbed.h"
dreschpe 0:da1bf437cbc1 21
dreschpe 0:da1bf437cbc1 22 #define BPP 16 // Bits per pixel
dreschpe 6:fe07ae8329f7 23
dreschpe 0:da1bf437cbc1 24 //extern Serial pc;
dreschpe 0:da1bf437cbc1 25 //extern DigitalOut xx; // debug !!
dreschpe 0:da1bf437cbc1 26
dreschpe 0:da1bf437cbc1 27 SPI_TFT_ILI9341::SPI_TFT_ILI9341(PinName mosi, PinName miso, PinName sclk, PinName cs, PinName reset, PinName dc, const char *name)
dreschpe 0:da1bf437cbc1 28 : _spi(mosi, miso, sclk), _cs(cs), _reset(reset), _dc(dc), GraphicsDisplay(name)
dreschpe 0:da1bf437cbc1 29 {
dreschpe 6:fe07ae8329f7 30 clk = sclk;
dreschpe 0:da1bf437cbc1 31 orientation = 0;
dreschpe 0:da1bf437cbc1 32 char_x = 0;
dreschpe 0:da1bf437cbc1 33 tft_reset();
dreschpe 0:da1bf437cbc1 34 }
dreschpe 0:da1bf437cbc1 35
dreschpe 0:da1bf437cbc1 36 int SPI_TFT_ILI9341::width()
dreschpe 0:da1bf437cbc1 37 {
dreschpe 0:da1bf437cbc1 38 if (orientation == 0 || orientation == 2) return 240;
dreschpe 0:da1bf437cbc1 39 else return 320;
dreschpe 0:da1bf437cbc1 40 }
dreschpe 0:da1bf437cbc1 41
dreschpe 0:da1bf437cbc1 42
dreschpe 0:da1bf437cbc1 43 int SPI_TFT_ILI9341::height()
dreschpe 0:da1bf437cbc1 44 {
dreschpe 0:da1bf437cbc1 45 if (orientation == 0 || orientation == 2) return 320;
dreschpe 0:da1bf437cbc1 46 else return 240;
dreschpe 0:da1bf437cbc1 47 }
dreschpe 0:da1bf437cbc1 48
dreschpe 0:da1bf437cbc1 49
dreschpe 2:0a16083193a4 50 void SPI_TFT_ILI9341::set_orientation(unsigned int o)
dreschpe 0:da1bf437cbc1 51 {
dreschpe 0:da1bf437cbc1 52 orientation = o;
dreschpe 2:0a16083193a4 53 wr_cmd(0x36); // MEMORY_ACCESS_CONTROL
dreschpe 0:da1bf437cbc1 54 switch (orientation) {
dreschpe 0:da1bf437cbc1 55 case 0:
dreschpe 2:0a16083193a4 56 _spi.write(0x48);
dreschpe 0:da1bf437cbc1 57 break;
dreschpe 0:da1bf437cbc1 58 case 1:
dreschpe 2:0a16083193a4 59 _spi.write(0x28);
dreschpe 0:da1bf437cbc1 60 break;
dreschpe 0:da1bf437cbc1 61 case 2:
dreschpe 2:0a16083193a4 62 _spi.write(0x88);
dreschpe 0:da1bf437cbc1 63 break;
dreschpe 0:da1bf437cbc1 64 case 3:
dreschpe 2:0a16083193a4 65 _spi.write(0xE8);
dreschpe 0:da1bf437cbc1 66 break;
dreschpe 0:da1bf437cbc1 67 }
dreschpe 2:0a16083193a4 68 _cs = 1;
dreschpe 0:da1bf437cbc1 69 WindowMax();
dreschpe 2:0a16083193a4 70 }
dreschpe 0:da1bf437cbc1 71
dreschpe 0:da1bf437cbc1 72
dreschpe 0:da1bf437cbc1 73 // write command to tft register
dreschpe 0:da1bf437cbc1 74
dreschpe 0:da1bf437cbc1 75 void SPI_TFT_ILI9341::wr_cmd(unsigned char cmd)
dreschpe 0:da1bf437cbc1 76 {
dreschpe 0:da1bf437cbc1 77 _dc = 0;
dreschpe 0:da1bf437cbc1 78 _cs = 0;
dreschpe 0:da1bf437cbc1 79 _spi.write(cmd); // mbed lib
dreschpe 0:da1bf437cbc1 80 _dc = 1;
dreschpe 0:da1bf437cbc1 81 }
dreschpe 0:da1bf437cbc1 82
dreschpe 0:da1bf437cbc1 83
dreschpe 0:da1bf437cbc1 84
dreschpe 0:da1bf437cbc1 85 void SPI_TFT_ILI9341::wr_dat(unsigned char dat)
dreschpe 0:da1bf437cbc1 86 {
dreschpe 0:da1bf437cbc1 87 _spi.write(dat); // mbed lib
dreschpe 0:da1bf437cbc1 88 }
dreschpe 0:da1bf437cbc1 89
dreschpe 0:da1bf437cbc1 90
dreschpe 0:da1bf437cbc1 91
dreschpe 6:fe07ae8329f7 92 // the ILI9341 can read
dreschpe 6:fe07ae8329f7 93
dreschpe 6:fe07ae8329f7 94 char SPI_TFT_ILI9341::rd_byte(unsigned char cmd)
dreschpe 6:fe07ae8329f7 95 {
dreschpe 6:fe07ae8329f7 96 char r;
dreschpe 6:fe07ae8329f7 97 _dc = 0;
dreschpe 6:fe07ae8329f7 98 _cs = 0;
dreschpe 6:fe07ae8329f7 99 _spi.write(cmd); // mbed lib
dreschpe 6:fe07ae8329f7 100 _cs = 1;
dreschpe 6:fe07ae8329f7 101 r = _spi.write(0xff);
dreschpe 6:fe07ae8329f7 102 _cs = 1;
dreschpe 6:fe07ae8329f7 103 return(r);
dreschpe 6:fe07ae8329f7 104 }
dreschpe 0:da1bf437cbc1 105
dreschpe 6:fe07ae8329f7 106 // read 32 bit
dreschpe 6:fe07ae8329f7 107 int SPI_TFT_ILI9341::rd_32(unsigned char cmd)
dreschpe 6:fe07ae8329f7 108 {
dreschpe 6:fe07ae8329f7 109 int d;
dreschpe 6:fe07ae8329f7 110 char r;
dreschpe 6:fe07ae8329f7 111 _dc = 0;
dreschpe 6:fe07ae8329f7 112 _cs = 0;
dreschpe 6:fe07ae8329f7 113 d = cmd;
dreschpe 6:fe07ae8329f7 114 d = d << 1;
dreschpe 6:fe07ae8329f7 115 _spi.format(9,3); // we have to add a dummy clock cycle
dreschpe 6:fe07ae8329f7 116 _spi.write(d);
dreschpe 6:fe07ae8329f7 117 _spi.format(8,3);
dreschpe 6:fe07ae8329f7 118 _dc = 1;
dreschpe 6:fe07ae8329f7 119 r = _spi.write(0xff);
dreschpe 6:fe07ae8329f7 120 d = r;
dreschpe 6:fe07ae8329f7 121 r = _spi.write(0xff);
dreschpe 6:fe07ae8329f7 122 d = (d << 8) | r;
dreschpe 6:fe07ae8329f7 123 r = _spi.write(0xff);
dreschpe 6:fe07ae8329f7 124 d = (d << 8) | r;
dreschpe 6:fe07ae8329f7 125 r = _spi.write(0xff);
dreschpe 6:fe07ae8329f7 126 d = (d << 8) | r;
dreschpe 6:fe07ae8329f7 127 _cs = 1;
dreschpe 6:fe07ae8329f7 128 return(d);
dreschpe 6:fe07ae8329f7 129 }
dreschpe 0:da1bf437cbc1 130
dreschpe 6:fe07ae8329f7 131 int SPI_TFT_ILI9341::Read_ID(void){
dreschpe 6:fe07ae8329f7 132 int r;
dreschpe 6:fe07ae8329f7 133 r = rd_byte(0x0A);
dreschpe 6:fe07ae8329f7 134 r = rd_byte(0x0A);
dreschpe 6:fe07ae8329f7 135 r = rd_byte(0x0A);
dreschpe 6:fe07ae8329f7 136 r = rd_byte(0x0A);
dreschpe 6:fe07ae8329f7 137 return(r);
dreschpe 6:fe07ae8329f7 138 }
dreschpe 0:da1bf437cbc1 139
dreschpe 0:da1bf437cbc1 140
dreschpe 1:6d6125e88de7 141 // Init code based on MI0283QT datasheet
dreschpe 1:6d6125e88de7 142
dreschpe 0:da1bf437cbc1 143 void SPI_TFT_ILI9341::tft_reset()
dreschpe 0:da1bf437cbc1 144 {
dreschpe 2:0a16083193a4 145 _spi.format(8,3); // 8 bit spi mode 3
dreschpe 6:fe07ae8329f7 146 _spi.frequency(20000000); // 10 Mhz SPI clock
dreschpe 0:da1bf437cbc1 147 _cs = 1; // cs high
dreschpe 0:da1bf437cbc1 148 _dc = 1; // dc high
dreschpe 0:da1bf437cbc1 149 _reset = 0; // display reset
dreschpe 0:da1bf437cbc1 150
dreschpe 0:da1bf437cbc1 151 wait_us(50);
dreschpe 1:6d6125e88de7 152 _reset = 1; // end hardware reset
dreschpe 0:da1bf437cbc1 153 wait_ms(5);
dreschpe 1:6d6125e88de7 154
dreschpe 1:6d6125e88de7 155 wr_cmd(0x01); // SW reset
dreschpe 1:6d6125e88de7 156 wait_ms(5);
dreschpe 1:6d6125e88de7 157 wr_cmd(0x28); // display off
dreschpe 0:da1bf437cbc1 158
dreschpe 0:da1bf437cbc1 159 /* Start Initial Sequence ----------------------------------------------------*/
dreschpe 1:6d6125e88de7 160 wr_cmd(0xCF);
dreschpe 1:6d6125e88de7 161 _spi.write(0x00);
dreschpe 1:6d6125e88de7 162 _spi.write(0x83);
dreschpe 1:6d6125e88de7 163 _spi.write(0x30);
dreschpe 1:6d6125e88de7 164 _cs = 1;
dreschpe 1:6d6125e88de7 165
dreschpe 1:6d6125e88de7 166 wr_cmd(0xED);
dreschpe 1:6d6125e88de7 167 _spi.write(0x64);
dreschpe 1:6d6125e88de7 168 _spi.write(0x03);
dreschpe 1:6d6125e88de7 169 _spi.write(0x12);
dreschpe 1:6d6125e88de7 170 _spi.write(0x81);
dreschpe 1:6d6125e88de7 171 _cs = 1;
dreschpe 1:6d6125e88de7 172
dreschpe 1:6d6125e88de7 173 wr_cmd(0xE8);
dreschpe 1:6d6125e88de7 174 _spi.write(0x85);
dreschpe 1:6d6125e88de7 175 _spi.write(0x01);
dreschpe 1:6d6125e88de7 176 _spi.write(0x79);
dreschpe 1:6d6125e88de7 177 _cs = 1;
dreschpe 1:6d6125e88de7 178
dreschpe 1:6d6125e88de7 179 wr_cmd(0xCB);
dreschpe 0:da1bf437cbc1 180 _spi.write(0x39);
dreschpe 0:da1bf437cbc1 181 _spi.write(0x2C);
dreschpe 0:da1bf437cbc1 182 _spi.write(0x00);
dreschpe 0:da1bf437cbc1 183 _spi.write(0x34);
dreschpe 0:da1bf437cbc1 184 _spi.write(0x02);
dreschpe 0:da1bf437cbc1 185 _cs = 1;
dreschpe 1:6d6125e88de7 186
dreschpe 1:6d6125e88de7 187 wr_cmd(0xF7);
dreschpe 1:6d6125e88de7 188 _spi.write(0x20);
dreschpe 0:da1bf437cbc1 189 _cs = 1;
dreschpe 1:6d6125e88de7 190
dreschpe 1:6d6125e88de7 191 wr_cmd(0xEA);
dreschpe 1:6d6125e88de7 192 _spi.write(0x00);
dreschpe 1:6d6125e88de7 193 _spi.write(0x00);
dreschpe 0:da1bf437cbc1 194 _cs = 1;
dreschpe 1:6d6125e88de7 195
dreschpe 0:da1bf437cbc1 196 wr_cmd(0xC0); // POWER_CONTROL_1
dreschpe 1:6d6125e88de7 197 _spi.write(0x26);
dreschpe 0:da1bf437cbc1 198 _cs = 1;
dreschpe 1:6d6125e88de7 199
dreschpe 0:da1bf437cbc1 200 wr_cmd(0xC1); // POWER_CONTROL_2
dreschpe 0:da1bf437cbc1 201 _spi.write(0x11);
dreschpe 0:da1bf437cbc1 202 _cs = 1;
dreschpe 1:6d6125e88de7 203
dreschpe 0:da1bf437cbc1 204 wr_cmd(0xC5); // VCOM_CONTROL_1
dreschpe 1:6d6125e88de7 205 _spi.write(0x35);
dreschpe 1:6d6125e88de7 206 _spi.write(0x3E);
dreschpe 0:da1bf437cbc1 207 _cs = 1;
dreschpe 1:6d6125e88de7 208
dreschpe 0:da1bf437cbc1 209 wr_cmd(0xC7); // VCOM_CONTROL_2
dreschpe 1:6d6125e88de7 210 _spi.write(0xBE);
dreschpe 0:da1bf437cbc1 211 _cs = 1;
dreschpe 1:6d6125e88de7 212
dreschpe 0:da1bf437cbc1 213 wr_cmd(0x36); // MEMORY_ACCESS_CONTROL
dreschpe 0:da1bf437cbc1 214 _spi.write(0x48);
dreschpe 0:da1bf437cbc1 215 _cs = 1;
dreschpe 1:6d6125e88de7 216
dreschpe 1:6d6125e88de7 217 wr_cmd(0x3A); // COLMOD_PIXEL_FORMAT_SET
dreschpe 1:6d6125e88de7 218 _spi.write(0x55); // 16 bit pixel
dreschpe 1:6d6125e88de7 219 _cs = 1;
dreschpe 1:6d6125e88de7 220
dreschpe 1:6d6125e88de7 221 wr_cmd(0xB1); // Frame Rate
dreschpe 1:6d6125e88de7 222 _spi.write(0x00);
dreschpe 1:6d6125e88de7 223 _spi.write(0x1B);
dreschpe 1:6d6125e88de7 224 _cs = 1;
dreschpe 1:6d6125e88de7 225
dreschpe 1:6d6125e88de7 226 wr_cmd(0xF2); // Gamma Function Disable
dreschpe 1:6d6125e88de7 227 _spi.write(0x08);
dreschpe 1:6d6125e88de7 228 _cs = 1;
dreschpe 1:6d6125e88de7 229
dreschpe 1:6d6125e88de7 230 wr_cmd(0x26);
dreschpe 1:6d6125e88de7 231 _spi.write(0x01); // gamma set for curve 01/2/04/08
dreschpe 1:6d6125e88de7 232 _cs = 1;
dreschpe 1:6d6125e88de7 233
dreschpe 1:6d6125e88de7 234 wr_cmd(0xE0); // positive gamma correction
dreschpe 1:6d6125e88de7 235 _spi.write(0x1F);
dreschpe 1:6d6125e88de7 236 _spi.write(0x1A);
dreschpe 1:6d6125e88de7 237 _spi.write(0x18);
dreschpe 1:6d6125e88de7 238 _spi.write(0x0A);
dreschpe 1:6d6125e88de7 239 _spi.write(0x0F);
dreschpe 1:6d6125e88de7 240 _spi.write(0x06);
dreschpe 1:6d6125e88de7 241 _spi.write(0x45);
dreschpe 1:6d6125e88de7 242 _spi.write(0x87);
dreschpe 1:6d6125e88de7 243 _spi.write(0x32);
dreschpe 1:6d6125e88de7 244 _spi.write(0x0A);
dreschpe 1:6d6125e88de7 245 _spi.write(0x07);
dreschpe 1:6d6125e88de7 246 _spi.write(0x02);
dreschpe 1:6d6125e88de7 247 _spi.write(0x07);
dreschpe 1:6d6125e88de7 248 _spi.write(0x05);
dreschpe 1:6d6125e88de7 249 _spi.write(0x00);
dreschpe 1:6d6125e88de7 250 _cs = 1;
dreschpe 1:6d6125e88de7 251
dreschpe 1:6d6125e88de7 252 wr_cmd(0xE1); // negativ gamma correction
dreschpe 1:6d6125e88de7 253 _spi.write(0x00);
dreschpe 1:6d6125e88de7 254 _spi.write(0x25);
dreschpe 1:6d6125e88de7 255 _spi.write(0x27);
dreschpe 1:6d6125e88de7 256 _spi.write(0x05);
dreschpe 1:6d6125e88de7 257 _spi.write(0x10);
dreschpe 1:6d6125e88de7 258 _spi.write(0x09);
dreschpe 1:6d6125e88de7 259 _spi.write(0x3A);
dreschpe 1:6d6125e88de7 260 _spi.write(0x78);
dreschpe 1:6d6125e88de7 261 _spi.write(0x4D);
dreschpe 1:6d6125e88de7 262 _spi.write(0x05);
dreschpe 1:6d6125e88de7 263 _spi.write(0x18);
dreschpe 1:6d6125e88de7 264 _spi.write(0x0D);
dreschpe 1:6d6125e88de7 265 _spi.write(0x38);
dreschpe 1:6d6125e88de7 266 _spi.write(0x3A);
dreschpe 1:6d6125e88de7 267 _spi.write(0x1F);
dreschpe 1:6d6125e88de7 268 _cs = 1;
dreschpe 1:6d6125e88de7 269
dreschpe 1:6d6125e88de7 270 WindowMax ();
dreschpe 1:6d6125e88de7 271
dreschpe 1:6d6125e88de7 272 //wr_cmd(0x34); // tearing effect off
dreschpe 1:6d6125e88de7 273 //_cs = 1;
dreschpe 1:6d6125e88de7 274
dreschpe 1:6d6125e88de7 275 //wr_cmd(0x35); // tearing effect on
dreschpe 1:6d6125e88de7 276 //_cs = 1;
dreschpe 1:6d6125e88de7 277
dreschpe 1:6d6125e88de7 278 wr_cmd(0xB7); // entry mode
dreschpe 1:6d6125e88de7 279 _spi.write(0x07);
dreschpe 1:6d6125e88de7 280 _cs = 1;
dreschpe 1:6d6125e88de7 281
dreschpe 1:6d6125e88de7 282 wr_cmd(0xB6); // display function control
dreschpe 1:6d6125e88de7 283 _spi.write(0x0A);
dreschpe 1:6d6125e88de7 284 _spi.write(0x82);
dreschpe 1:6d6125e88de7 285 _spi.write(0x27);
dreschpe 1:6d6125e88de7 286 _spi.write(0x00);
dreschpe 1:6d6125e88de7 287 _cs = 1;
dreschpe 1:6d6125e88de7 288
dreschpe 1:6d6125e88de7 289 wr_cmd(0x11); // sleep out
dreschpe 1:6d6125e88de7 290 _cs = 1;
dreschpe 1:6d6125e88de7 291
dreschpe 1:6d6125e88de7 292 wait_ms(100);
dreschpe 1:6d6125e88de7 293
dreschpe 1:6d6125e88de7 294 wr_cmd(0x29); // display on
dreschpe 1:6d6125e88de7 295 _cs = 1;
dreschpe 1:6d6125e88de7 296
dreschpe 1:6d6125e88de7 297 wait_ms(100);
dreschpe 1:6d6125e88de7 298
dreschpe 1:6d6125e88de7 299 }
dreschpe 0:da1bf437cbc1 300
dreschpe 0:da1bf437cbc1 301
dreschpe 0:da1bf437cbc1 302 void SPI_TFT_ILI9341::pixel(int x, int y, int color)
dreschpe 0:da1bf437cbc1 303 {
dreschpe 0:da1bf437cbc1 304 wr_cmd(0x2A);
dreschpe 0:da1bf437cbc1 305 _spi.write(x >> 8);
dreschpe 0:da1bf437cbc1 306 _spi.write(x);
dreschpe 0:da1bf437cbc1 307 _cs = 1;
dreschpe 0:da1bf437cbc1 308 wr_cmd(0x2B);
dreschpe 0:da1bf437cbc1 309 _spi.write(y >> 8);
dreschpe 0:da1bf437cbc1 310 _spi.write(y);
dreschpe 0:da1bf437cbc1 311 _cs = 1;
dreschpe 5:55aed13f2630 312 wr_cmd(0x2C); // send pixel
dreschpe 5:55aed13f2630 313 #if defined TARGET_KL25Z // 8 Bit SPI
dreschpe 5:55aed13f2630 314 _spi.write(color >> 8);
dreschpe 5:55aed13f2630 315 _spi.write(color & 0xff);
dreschpe 5:55aed13f2630 316 #else
dreschpe 0:da1bf437cbc1 317 _spi.format(16,3); // switch to 16 bit Mode 3
dreschpe 0:da1bf437cbc1 318 _spi.write(color); // Write D0..D15
dreschpe 0:da1bf437cbc1 319 _spi.format(8,3);
dreschpe 5:55aed13f2630 320 #endif
dreschpe 0:da1bf437cbc1 321 _cs = 1;
dreschpe 0:da1bf437cbc1 322 }
dreschpe 0:da1bf437cbc1 323
dreschpe 0:da1bf437cbc1 324
dreschpe 0:da1bf437cbc1 325 void SPI_TFT_ILI9341::window (unsigned int x, unsigned int y, unsigned int w, unsigned int h)
dreschpe 0:da1bf437cbc1 326 {
dreschpe 0:da1bf437cbc1 327 wr_cmd(0x2A);
dreschpe 0:da1bf437cbc1 328 _spi.write(x >> 8);
dreschpe 0:da1bf437cbc1 329 _spi.write(x);
dreschpe 0:da1bf437cbc1 330 _spi.write((x+w-1) >> 8);
dreschpe 0:da1bf437cbc1 331 _spi.write(x+w-1);
dreschpe 0:da1bf437cbc1 332
dreschpe 0:da1bf437cbc1 333 _cs = 1;
dreschpe 0:da1bf437cbc1 334 wr_cmd(0x2B);
dreschpe 0:da1bf437cbc1 335 _spi.write(y >> 8);
dreschpe 0:da1bf437cbc1 336 _spi.write(y);
dreschpe 0:da1bf437cbc1 337 _spi.write((y+h-1) >> 8);
dreschpe 0:da1bf437cbc1 338 _spi.write(y+h-1);
dreschpe 0:da1bf437cbc1 339 _cs = 1;
dreschpe 0:da1bf437cbc1 340 }
dreschpe 0:da1bf437cbc1 341
dreschpe 0:da1bf437cbc1 342
dreschpe 0:da1bf437cbc1 343 void SPI_TFT_ILI9341::WindowMax (void)
dreschpe 0:da1bf437cbc1 344 {
dreschpe 0:da1bf437cbc1 345 window (0, 0, width(), height());
dreschpe 0:da1bf437cbc1 346 }
dreschpe 0:da1bf437cbc1 347
dreschpe 0:da1bf437cbc1 348
dreschpe 0:da1bf437cbc1 349
dreschpe 0:da1bf437cbc1 350 void SPI_TFT_ILI9341::cls (void)
dreschpe 0:da1bf437cbc1 351 {
dreschpe 0:da1bf437cbc1 352 int pixel = ( width() * height());
dreschpe 0:da1bf437cbc1 353 WindowMax();
dreschpe 5:55aed13f2630 354 wr_cmd(0x2C); // send pixel
dreschpe 5:55aed13f2630 355 #if defined TARGET_KL25Z // 8 Bit SPI
dreschpe 5:55aed13f2630 356 unsigned int i;
dreschpe 5:55aed13f2630 357 for (i = 0; i < ( width() * height()); i++){
dreschpe 5:55aed13f2630 358 _spi.write(_background >> 8);
dreschpe 5:55aed13f2630 359 _spi.write(_background & 0xff);
dreschpe 5:55aed13f2630 360 }
dreschpe 5:55aed13f2630 361
dreschpe 5:55aed13f2630 362 #else
dreschpe 0:da1bf437cbc1 363 _spi.format(16,3); // switch to 16 bit Mode 3
dreschpe 0:da1bf437cbc1 364 unsigned int i;
dreschpe 0:da1bf437cbc1 365 for (i = 0; i < ( width() * height()); i++)
dreschpe 5:55aed13f2630 366 _spi.write(_background);
dreschpe 5:55aed13f2630 367 _spi.format(8,3);
dreschpe 5:55aed13f2630 368 #endif
dreschpe 5:55aed13f2630 369 _cs = 1;
dreschpe 0:da1bf437cbc1 370 }
dreschpe 0:da1bf437cbc1 371
dreschpe 0:da1bf437cbc1 372
dreschpe 0:da1bf437cbc1 373 void SPI_TFT_ILI9341::circle(int x0, int y0, int r, int color)
dreschpe 0:da1bf437cbc1 374 {
dreschpe 0:da1bf437cbc1 375
mazgch 3:3d7298360e45 376 int x = -r, y = 0, err = 2-2*r, e2;
mazgch 3:3d7298360e45 377 do {
mazgch 3:3d7298360e45 378 pixel(x0-x, y0+y,color);
mazgch 3:3d7298360e45 379 pixel(x0+x, y0+y,color);
mazgch 3:3d7298360e45 380 pixel(x0+x, y0-y,color);
mazgch 3:3d7298360e45 381 pixel(x0-x, y0-y,color);
mazgch 3:3d7298360e45 382 e2 = err;
mazgch 3:3d7298360e45 383 if (e2 <= y) {
mazgch 3:3d7298360e45 384 err += ++y*2+1;
mazgch 3:3d7298360e45 385 if (-x == y && e2 <= x) e2 = 0;
mazgch 3:3d7298360e45 386 }
mazgch 3:3d7298360e45 387 if (e2 > x) err += ++x*2+1;
mazgch 3:3d7298360e45 388 } while (x <= 0);
dreschpe 4:f018e272220b 389
dreschpe 0:da1bf437cbc1 390 }
dreschpe 0:da1bf437cbc1 391
mazgch 3:3d7298360e45 392 void SPI_TFT_ILI9341::fillcircle(int x0, int y0, int r, int color)
dreschpe 0:da1bf437cbc1 393 {
mazgch 3:3d7298360e45 394 int x = -r, y = 0, err = 2-2*r, e2;
mazgch 3:3d7298360e45 395 do {
mazgch 3:3d7298360e45 396 vline(x0-x, y0-y, y0+y, color);
mazgch 3:3d7298360e45 397 vline(x0+x, y0-y, y0+y, color);
mazgch 3:3d7298360e45 398 e2 = err;
mazgch 3:3d7298360e45 399 if (e2 <= y) {
mazgch 3:3d7298360e45 400 err += ++y*2+1;
mazgch 3:3d7298360e45 401 if (-x == y && e2 <= x) e2 = 0;
mazgch 3:3d7298360e45 402 }
mazgch 3:3d7298360e45 403 if (e2 > x) err += ++x*2+1;
mazgch 3:3d7298360e45 404 } while (x <= 0);
dreschpe 0:da1bf437cbc1 405 }
dreschpe 0:da1bf437cbc1 406
dreschpe 0:da1bf437cbc1 407
dreschpe 0:da1bf437cbc1 408 void SPI_TFT_ILI9341::hline(int x0, int x1, int y, int color)
dreschpe 0:da1bf437cbc1 409 {
dreschpe 0:da1bf437cbc1 410 int w;
dreschpe 0:da1bf437cbc1 411 w = x1 - x0 + 1;
dreschpe 0:da1bf437cbc1 412 window(x0,y,w,1);
dreschpe 5:55aed13f2630 413 wr_cmd(0x2C); // send pixel
dreschpe 5:55aed13f2630 414 #if defined TARGET_KL25Z // 8 Bit SPI
dreschpe 5:55aed13f2630 415 int j;
dreschpe 5:55aed13f2630 416 for (j=0; j<w; j++) {
dreschpe 5:55aed13f2630 417 _spi.write(color >> 8);
dreschpe 5:55aed13f2630 418 _spi.write(color & 0xff);
dreschpe 5:55aed13f2630 419 }
dreschpe 5:55aed13f2630 420 #else
dreschpe 0:da1bf437cbc1 421 _spi.format(16,3); // switch to 16 bit Mode 3
dreschpe 0:da1bf437cbc1 422 int j;
dreschpe 0:da1bf437cbc1 423 for (j=0; j<w; j++) {
dreschpe 0:da1bf437cbc1 424 _spi.write(color);
dreschpe 0:da1bf437cbc1 425 }
dreschpe 5:55aed13f2630 426 _spi.format(8,3);
dreschpe 5:55aed13f2630 427 #endif
dreschpe 0:da1bf437cbc1 428 _cs = 1;
dreschpe 0:da1bf437cbc1 429 WindowMax();
dreschpe 0:da1bf437cbc1 430 return;
dreschpe 0:da1bf437cbc1 431 }
dreschpe 0:da1bf437cbc1 432
dreschpe 0:da1bf437cbc1 433 void SPI_TFT_ILI9341::vline(int x, int y0, int y1, int color)
dreschpe 0:da1bf437cbc1 434 {
dreschpe 0:da1bf437cbc1 435 int h;
dreschpe 0:da1bf437cbc1 436 h = y1 - y0 + 1;
dreschpe 0:da1bf437cbc1 437 window(x,y0,1,h);
dreschpe 5:55aed13f2630 438 wr_cmd(0x2C); // send pixel
dreschpe 5:55aed13f2630 439 #if defined TARGET_KL25Z // 8 Bit SPI
dreschpe 5:55aed13f2630 440 for (int y=0; y<h; y++) {
dreschpe 5:55aed13f2630 441 _spi.write(color >> 8);
dreschpe 5:55aed13f2630 442 _spi.write(color & 0xff);
dreschpe 5:55aed13f2630 443 }
dreschpe 5:55aed13f2630 444 #else
dreschpe 0:da1bf437cbc1 445 _spi.format(16,3); // switch to 16 bit Mode 3
dreschpe 0:da1bf437cbc1 446 for (int y=0; y<h; y++) {
dreschpe 0:da1bf437cbc1 447 _spi.write(color);
dreschpe 0:da1bf437cbc1 448 }
dreschpe 5:55aed13f2630 449 _spi.format(8,3);
dreschpe 5:55aed13f2630 450 #endif
dreschpe 0:da1bf437cbc1 451 _cs = 1;
dreschpe 0:da1bf437cbc1 452 WindowMax();
dreschpe 0:da1bf437cbc1 453 return;
dreschpe 0:da1bf437cbc1 454 }
dreschpe 0:da1bf437cbc1 455
dreschpe 0:da1bf437cbc1 456
dreschpe 0:da1bf437cbc1 457
dreschpe 0:da1bf437cbc1 458 void SPI_TFT_ILI9341::line(int x0, int y0, int x1, int y1, int color)
dreschpe 0:da1bf437cbc1 459 {
dreschpe 0:da1bf437cbc1 460 //WindowMax();
dreschpe 0:da1bf437cbc1 461 int dx = 0, dy = 0;
dreschpe 0:da1bf437cbc1 462 int dx_sym = 0, dy_sym = 0;
dreschpe 0:da1bf437cbc1 463 int dx_x2 = 0, dy_x2 = 0;
dreschpe 0:da1bf437cbc1 464 int di = 0;
dreschpe 0:da1bf437cbc1 465
dreschpe 0:da1bf437cbc1 466 dx = x1-x0;
dreschpe 0:da1bf437cbc1 467 dy = y1-y0;
dreschpe 0:da1bf437cbc1 468
dreschpe 0:da1bf437cbc1 469 if (dx == 0) { /* vertical line */
dreschpe 0:da1bf437cbc1 470 if (y1 > y0) vline(x0,y0,y1,color);
dreschpe 0:da1bf437cbc1 471 else vline(x0,y1,y0,color);
dreschpe 0:da1bf437cbc1 472 return;
dreschpe 0:da1bf437cbc1 473 }
dreschpe 0:da1bf437cbc1 474
dreschpe 0:da1bf437cbc1 475 if (dx > 0) {
dreschpe 0:da1bf437cbc1 476 dx_sym = 1;
dreschpe 0:da1bf437cbc1 477 } else {
dreschpe 0:da1bf437cbc1 478 dx_sym = -1;
dreschpe 0:da1bf437cbc1 479 }
dreschpe 0:da1bf437cbc1 480 if (dy == 0) { /* horizontal line */
dreschpe 0:da1bf437cbc1 481 if (x1 > x0) hline(x0,x1,y0,color);
dreschpe 0:da1bf437cbc1 482 else hline(x1,x0,y0,color);
dreschpe 0:da1bf437cbc1 483 return;
dreschpe 0:da1bf437cbc1 484 }
dreschpe 0:da1bf437cbc1 485
dreschpe 0:da1bf437cbc1 486 if (dy > 0) {
dreschpe 0:da1bf437cbc1 487 dy_sym = 1;
dreschpe 0:da1bf437cbc1 488 } else {
dreschpe 0:da1bf437cbc1 489 dy_sym = -1;
dreschpe 0:da1bf437cbc1 490 }
dreschpe 0:da1bf437cbc1 491
dreschpe 0:da1bf437cbc1 492 dx = dx_sym*dx;
dreschpe 0:da1bf437cbc1 493 dy = dy_sym*dy;
dreschpe 0:da1bf437cbc1 494
dreschpe 0:da1bf437cbc1 495 dx_x2 = dx*2;
dreschpe 0:da1bf437cbc1 496 dy_x2 = dy*2;
dreschpe 0:da1bf437cbc1 497
dreschpe 0:da1bf437cbc1 498 if (dx >= dy) {
dreschpe 0:da1bf437cbc1 499 di = dy_x2 - dx;
dreschpe 0:da1bf437cbc1 500 while (x0 != x1) {
dreschpe 0:da1bf437cbc1 501
dreschpe 0:da1bf437cbc1 502 pixel(x0, y0, color);
dreschpe 0:da1bf437cbc1 503 x0 += dx_sym;
dreschpe 0:da1bf437cbc1 504 if (di<0) {
dreschpe 0:da1bf437cbc1 505 di += dy_x2;
dreschpe 0:da1bf437cbc1 506 } else {
dreschpe 0:da1bf437cbc1 507 di += dy_x2 - dx_x2;
dreschpe 0:da1bf437cbc1 508 y0 += dy_sym;
dreschpe 0:da1bf437cbc1 509 }
dreschpe 0:da1bf437cbc1 510 }
dreschpe 0:da1bf437cbc1 511 pixel(x0, y0, color);
dreschpe 0:da1bf437cbc1 512 } else {
dreschpe 0:da1bf437cbc1 513 di = dx_x2 - dy;
dreschpe 0:da1bf437cbc1 514 while (y0 != y1) {
dreschpe 0:da1bf437cbc1 515 pixel(x0, y0, color);
dreschpe 0:da1bf437cbc1 516 y0 += dy_sym;
dreschpe 0:da1bf437cbc1 517 if (di < 0) {
dreschpe 0:da1bf437cbc1 518 di += dx_x2;
dreschpe 0:da1bf437cbc1 519 } else {
dreschpe 0:da1bf437cbc1 520 di += dx_x2 - dy_x2;
dreschpe 0:da1bf437cbc1 521 x0 += dx_sym;
dreschpe 0:da1bf437cbc1 522 }
dreschpe 0:da1bf437cbc1 523 }
dreschpe 0:da1bf437cbc1 524 pixel(x0, y0, color);
dreschpe 0:da1bf437cbc1 525 }
dreschpe 0:da1bf437cbc1 526 return;
dreschpe 0:da1bf437cbc1 527 }
dreschpe 0:da1bf437cbc1 528
dreschpe 0:da1bf437cbc1 529
dreschpe 0:da1bf437cbc1 530 void SPI_TFT_ILI9341::rect(int x0, int y0, int x1, int y1, int color)
dreschpe 0:da1bf437cbc1 531 {
dreschpe 0:da1bf437cbc1 532
dreschpe 0:da1bf437cbc1 533 if (x1 > x0) hline(x0,x1,y0,color);
dreschpe 0:da1bf437cbc1 534 else hline(x1,x0,y0,color);
dreschpe 0:da1bf437cbc1 535
dreschpe 0:da1bf437cbc1 536 if (y1 > y0) vline(x0,y0,y1,color);
dreschpe 0:da1bf437cbc1 537 else vline(x0,y1,y0,color);
dreschpe 0:da1bf437cbc1 538
dreschpe 0:da1bf437cbc1 539 if (x1 > x0) hline(x0,x1,y1,color);
dreschpe 0:da1bf437cbc1 540 else hline(x1,x0,y1,color);
dreschpe 0:da1bf437cbc1 541
dreschpe 0:da1bf437cbc1 542 if (y1 > y0) vline(x1,y0,y1,color);
dreschpe 0:da1bf437cbc1 543 else vline(x1,y1,y0,color);
dreschpe 0:da1bf437cbc1 544
dreschpe 0:da1bf437cbc1 545 return;
dreschpe 0:da1bf437cbc1 546 }
dreschpe 0:da1bf437cbc1 547
dreschpe 0:da1bf437cbc1 548
dreschpe 0:da1bf437cbc1 549
dreschpe 0:da1bf437cbc1 550 void SPI_TFT_ILI9341::fillrect(int x0, int y0, int x1, int y1, int color)
dreschpe 0:da1bf437cbc1 551 {
dreschpe 0:da1bf437cbc1 552
dreschpe 0:da1bf437cbc1 553 int h = y1 - y0 + 1;
dreschpe 0:da1bf437cbc1 554 int w = x1 - x0 + 1;
dreschpe 0:da1bf437cbc1 555 int pixel = h * w;
dreschpe 0:da1bf437cbc1 556 window(x0,y0,w,h);
dreschpe 0:da1bf437cbc1 557 wr_cmd(0x2C); // send pixel
dreschpe 5:55aed13f2630 558 #if defined TARGET_KL25Z // 8 Bit SPI
dreschpe 5:55aed13f2630 559 for (int p=0; p<pixel; p++) {
dreschpe 5:55aed13f2630 560 _spi.write(color >> 8);
dreschpe 5:55aed13f2630 561 _spi.write(color & 0xff);
dreschpe 5:55aed13f2630 562 }
dreschpe 5:55aed13f2630 563 #else
dreschpe 0:da1bf437cbc1 564 _spi.format(16,3); // switch to 16 bit Mode 3
dreschpe 0:da1bf437cbc1 565 for (int p=0; p<pixel; p++) {
dreschpe 0:da1bf437cbc1 566 _spi.write(color);
dreschpe 0:da1bf437cbc1 567 }
dreschpe 5:55aed13f2630 568 _spi.format(8,3);
dreschpe 5:55aed13f2630 569 #endif
dreschpe 0:da1bf437cbc1 570 _cs = 1;
dreschpe 0:da1bf437cbc1 571 WindowMax();
dreschpe 0:da1bf437cbc1 572 return;
dreschpe 0:da1bf437cbc1 573 }
dreschpe 0:da1bf437cbc1 574
dreschpe 0:da1bf437cbc1 575
dreschpe 0:da1bf437cbc1 576 void SPI_TFT_ILI9341::locate(int x, int y)
dreschpe 0:da1bf437cbc1 577 {
dreschpe 0:da1bf437cbc1 578 char_x = x;
dreschpe 0:da1bf437cbc1 579 char_y = y;
dreschpe 0:da1bf437cbc1 580 }
dreschpe 0:da1bf437cbc1 581
dreschpe 0:da1bf437cbc1 582
dreschpe 0:da1bf437cbc1 583
dreschpe 0:da1bf437cbc1 584 int SPI_TFT_ILI9341::columns()
dreschpe 0:da1bf437cbc1 585 {
dreschpe 0:da1bf437cbc1 586 return width() / font[1];
dreschpe 0:da1bf437cbc1 587 }
dreschpe 0:da1bf437cbc1 588
dreschpe 0:da1bf437cbc1 589
dreschpe 0:da1bf437cbc1 590
dreschpe 0:da1bf437cbc1 591 int SPI_TFT_ILI9341::rows()
dreschpe 0:da1bf437cbc1 592 {
dreschpe 0:da1bf437cbc1 593 return height() / font[2];
dreschpe 0:da1bf437cbc1 594 }
dreschpe 0:da1bf437cbc1 595
dreschpe 0:da1bf437cbc1 596
dreschpe 0:da1bf437cbc1 597
dreschpe 0:da1bf437cbc1 598 int SPI_TFT_ILI9341::_putc(int value)
dreschpe 0:da1bf437cbc1 599 {
dreschpe 0:da1bf437cbc1 600 if (value == '\n') { // new line
dreschpe 0:da1bf437cbc1 601 char_x = 0;
dreschpe 0:da1bf437cbc1 602 char_y = char_y + font[2];
dreschpe 0:da1bf437cbc1 603 if (char_y >= height() - font[2]) {
dreschpe 0:da1bf437cbc1 604 char_y = 0;
dreschpe 0:da1bf437cbc1 605 }
dreschpe 0:da1bf437cbc1 606 } else {
dreschpe 0:da1bf437cbc1 607 character(char_x, char_y, value);
dreschpe 0:da1bf437cbc1 608 }
dreschpe 0:da1bf437cbc1 609 return value;
dreschpe 0:da1bf437cbc1 610 }
dreschpe 0:da1bf437cbc1 611
dreschpe 0:da1bf437cbc1 612
dreschpe 0:da1bf437cbc1 613 void SPI_TFT_ILI9341::character(int x, int y, int c)
dreschpe 0:da1bf437cbc1 614 {
dreschpe 0:da1bf437cbc1 615 unsigned int hor,vert,offset,bpl,j,i,b;
dreschpe 0:da1bf437cbc1 616 unsigned char* zeichen;
dreschpe 0:da1bf437cbc1 617 unsigned char z,w;
dreschpe 0:da1bf437cbc1 618
dreschpe 0:da1bf437cbc1 619 if ((c < 31) || (c > 127)) return; // test char range
dreschpe 0:da1bf437cbc1 620
dreschpe 0:da1bf437cbc1 621 // read font parameter from start of array
dreschpe 0:da1bf437cbc1 622 offset = font[0]; // bytes / char
dreschpe 0:da1bf437cbc1 623 hor = font[1]; // get hor size of font
dreschpe 0:da1bf437cbc1 624 vert = font[2]; // get vert size of font
dreschpe 0:da1bf437cbc1 625 bpl = font[3]; // bytes per line
dreschpe 0:da1bf437cbc1 626
dreschpe 0:da1bf437cbc1 627 if (char_x + hor > width()) {
dreschpe 0:da1bf437cbc1 628 char_x = 0;
dreschpe 0:da1bf437cbc1 629 char_y = char_y + vert;
dreschpe 0:da1bf437cbc1 630 if (char_y >= height() - font[2]) {
dreschpe 0:da1bf437cbc1 631 char_y = 0;
dreschpe 0:da1bf437cbc1 632 }
dreschpe 0:da1bf437cbc1 633 }
dreschpe 0:da1bf437cbc1 634 window(char_x, char_y,hor,vert); // char box
dreschpe 5:55aed13f2630 635 wr_cmd(0x2C); // send pixel
dreschpe 5:55aed13f2630 636 #ifndef TARGET_KL25Z // 16 Bit SPI
dreschpe 5:55aed13f2630 637 _spi.format(16,3);
dreschpe 5:55aed13f2630 638 #endif // switch to 16 bit Mode 3
dreschpe 0:da1bf437cbc1 639 zeichen = &font[((c -32) * offset) + 4]; // start of char bitmap
dreschpe 0:da1bf437cbc1 640 w = zeichen[0]; // width of actual char
dreschpe 0:da1bf437cbc1 641 for (j=0; j<vert; j++) { // vert line
dreschpe 0:da1bf437cbc1 642 for (i=0; i<hor; i++) { // horz line
dreschpe 0:da1bf437cbc1 643 z = zeichen[bpl * i + ((j & 0xF8) >> 3)+1];
dreschpe 0:da1bf437cbc1 644 b = 1 << (j & 0x07);
dreschpe 0:da1bf437cbc1 645 if (( z & b ) == 0x00) {
dreschpe 5:55aed13f2630 646 #ifndef TARGET_KL25Z // 16 Bit SPI
dreschpe 0:da1bf437cbc1 647 _spi.write(_background);
dreschpe 5:55aed13f2630 648 #else
dreschpe 5:55aed13f2630 649 _spi.write(_background >> 8);
dreschpe 5:55aed13f2630 650 _spi.write(_background & 0xff);
dreschpe 5:55aed13f2630 651 #endif
dreschpe 0:da1bf437cbc1 652 } else {
dreschpe 5:55aed13f2630 653 #ifndef TARGET_KL25Z // 16 Bit SPI
dreschpe 0:da1bf437cbc1 654 _spi.write(_foreground);
dreschpe 5:55aed13f2630 655 #else
dreschpe 5:55aed13f2630 656 _spi.write(_foreground >> 8);
dreschpe 5:55aed13f2630 657 _spi.write(_foreground & 0xff);
dreschpe 5:55aed13f2630 658 #endif
dreschpe 0:da1bf437cbc1 659 }
dreschpe 0:da1bf437cbc1 660 }
dreschpe 0:da1bf437cbc1 661 }
dreschpe 0:da1bf437cbc1 662 _cs = 1;
dreschpe 5:55aed13f2630 663 #ifndef TARGET_KL25Z // 16 Bit SPI
dreschpe 0:da1bf437cbc1 664 _spi.format(8,3);
dreschpe 5:55aed13f2630 665 #endif
dreschpe 0:da1bf437cbc1 666 WindowMax();
dreschpe 0:da1bf437cbc1 667 if ((w + 2) < hor) { // x offset to next char
dreschpe 0:da1bf437cbc1 668 char_x += w + 2;
dreschpe 0:da1bf437cbc1 669 } else char_x += hor;
dreschpe 0:da1bf437cbc1 670 }
dreschpe 0:da1bf437cbc1 671
dreschpe 0:da1bf437cbc1 672
dreschpe 0:da1bf437cbc1 673 void SPI_TFT_ILI9341::set_font(unsigned char* f)
dreschpe 0:da1bf437cbc1 674 {
dreschpe 0:da1bf437cbc1 675 font = f;
dreschpe 0:da1bf437cbc1 676 }
dreschpe 0:da1bf437cbc1 677
dreschpe 0:da1bf437cbc1 678
dreschpe 0:da1bf437cbc1 679
dreschpe 0:da1bf437cbc1 680 void SPI_TFT_ILI9341::Bitmap(unsigned int x, unsigned int y, unsigned int w, unsigned int h,unsigned char *bitmap)
dreschpe 0:da1bf437cbc1 681 {
dreschpe 0:da1bf437cbc1 682 unsigned int j;
dreschpe 0:da1bf437cbc1 683 int padd;
dreschpe 0:da1bf437cbc1 684 unsigned short *bitmap_ptr = (unsigned short *)bitmap;
dreschpe 5:55aed13f2630 685 #if defined TARGET_KL25Z // 8 Bit SPI
dreschpe 5:55aed13f2630 686 unsigned short pix_temp;
dreschpe 5:55aed13f2630 687 #endif
dreschpe 5:55aed13f2630 688
dreschpe 2:0a16083193a4 689 unsigned int i;
dreschpe 2:0a16083193a4 690
dreschpe 0:da1bf437cbc1 691 // the lines are padded to multiple of 4 bytes in a bitmap
dreschpe 0:da1bf437cbc1 692 padd = -1;
dreschpe 0:da1bf437cbc1 693 do {
dreschpe 0:da1bf437cbc1 694 padd ++;
dreschpe 0:da1bf437cbc1 695 } while (2*(w + padd)%4 != 0);
dreschpe 0:da1bf437cbc1 696 window(x, y, w, h);
dreschpe 2:0a16083193a4 697 bitmap_ptr += ((h - 1)* (w + padd));
dreschpe 5:55aed13f2630 698 wr_cmd(0x2C); // send pixel
dreschpe 5:55aed13f2630 699 #ifndef TARGET_KL25Z // 16 Bit SPI
dreschpe 5:55aed13f2630 700 _spi.format(16,3);
dreschpe 5:55aed13f2630 701 #endif // switch to 16 bit Mode 3
dreschpe 2:0a16083193a4 702 for (j = 0; j < h; j++) { //Lines
dreschpe 2:0a16083193a4 703 for (i = 0; i < w; i++) { // one line
dreschpe 5:55aed13f2630 704 #if defined TARGET_KL25Z // 8 Bit SPI
dreschpe 5:55aed13f2630 705 pix_temp = *bitmap_ptr;
dreschpe 5:55aed13f2630 706 _spi.write(pix_temp >> 8);
dreschpe 5:55aed13f2630 707 _spi.write(pix_temp);
dreschpe 5:55aed13f2630 708 bitmap_ptr++;
dreschpe 5:55aed13f2630 709 #else
dreschpe 5:55aed13f2630 710 _spi.write(*bitmap_ptr); // one line
dreschpe 5:55aed13f2630 711 bitmap_ptr++;
dreschpe 5:55aed13f2630 712 #endif
dreschpe 0:da1bf437cbc1 713 }
dreschpe 0:da1bf437cbc1 714 bitmap_ptr -= 2*w;
dreschpe 0:da1bf437cbc1 715 bitmap_ptr -= padd;
dreschpe 0:da1bf437cbc1 716 }
dreschpe 0:da1bf437cbc1 717 _cs = 1;
dreschpe 5:55aed13f2630 718 #ifndef TARGET_KL25Z // 16 Bit SPI
dreschpe 0:da1bf437cbc1 719 _spi.format(8,3);
dreschpe 5:55aed13f2630 720 #endif
dreschpe 0:da1bf437cbc1 721 WindowMax();
dreschpe 0:da1bf437cbc1 722 }
dreschpe 0:da1bf437cbc1 723
dreschpe 0:da1bf437cbc1 724
dreschpe 6:fe07ae8329f7 725 // local filesystem is not implemented in kinetis board , but you can add a SD card
dreschpe 5:55aed13f2630 726
dreschpe 0:da1bf437cbc1 727 int SPI_TFT_ILI9341::BMP_16(unsigned int x, unsigned int y, const char *Name_BMP)
dreschpe 0:da1bf437cbc1 728 {
dreschpe 0:da1bf437cbc1 729
dreschpe 0:da1bf437cbc1 730 #define OffsetPixelWidth 18
dreschpe 0:da1bf437cbc1 731 #define OffsetPixelHeigh 22
dreschpe 0:da1bf437cbc1 732 #define OffsetFileSize 34
dreschpe 0:da1bf437cbc1 733 #define OffsetPixData 10
dreschpe 0:da1bf437cbc1 734 #define OffsetBPP 28
dreschpe 0:da1bf437cbc1 735
dreschpe 0:da1bf437cbc1 736 char filename[50];
dreschpe 0:da1bf437cbc1 737 unsigned char BMP_Header[54];
dreschpe 0:da1bf437cbc1 738 unsigned short BPP_t;
dreschpe 0:da1bf437cbc1 739 unsigned int PixelWidth,PixelHeigh,start_data;
dreschpe 0:da1bf437cbc1 740 unsigned int i,off;
dreschpe 0:da1bf437cbc1 741 int padd,j;
dreschpe 0:da1bf437cbc1 742 unsigned short *line;
dreschpe 0:da1bf437cbc1 743
dreschpe 0:da1bf437cbc1 744 // get the filename
dreschpe 6:fe07ae8329f7 745 i=0;
dreschpe 0:da1bf437cbc1 746 while (*Name_BMP!='\0') {
dreschpe 0:da1bf437cbc1 747 filename[i++]=*Name_BMP++;
dreschpe 0:da1bf437cbc1 748 }
dreschpe 6:fe07ae8329f7 749 filename[i] = 0;
dreschpe 6:fe07ae8329f7 750
dreschpe 0:da1bf437cbc1 751 FILE *Image = fopen((const char *)&filename[0], "rb"); // open the bmp file
dreschpe 0:da1bf437cbc1 752 if (!Image) {
dreschpe 0:da1bf437cbc1 753 return(0); // error file not found !
dreschpe 0:da1bf437cbc1 754 }
dreschpe 0:da1bf437cbc1 755
dreschpe 0:da1bf437cbc1 756 fread(&BMP_Header[0],1,54,Image); // get the BMP Header
dreschpe 0:da1bf437cbc1 757
dreschpe 0:da1bf437cbc1 758 if (BMP_Header[0] != 0x42 || BMP_Header[1] != 0x4D) { // check magic byte
dreschpe 0:da1bf437cbc1 759 fclose(Image);
dreschpe 0:da1bf437cbc1 760 return(-1); // error no BMP file
dreschpe 0:da1bf437cbc1 761 }
dreschpe 0:da1bf437cbc1 762
dreschpe 0:da1bf437cbc1 763 BPP_t = BMP_Header[OffsetBPP] + (BMP_Header[OffsetBPP + 1] << 8);
dreschpe 0:da1bf437cbc1 764 if (BPP_t != 0x0010) {
dreschpe 0:da1bf437cbc1 765 fclose(Image);
dreschpe 0:da1bf437cbc1 766 return(-2); // error no 16 bit BMP
dreschpe 0:da1bf437cbc1 767 }
dreschpe 0:da1bf437cbc1 768
dreschpe 0:da1bf437cbc1 769 PixelHeigh = BMP_Header[OffsetPixelHeigh] + (BMP_Header[OffsetPixelHeigh + 1] << 8) + (BMP_Header[OffsetPixelHeigh + 2] << 16) + (BMP_Header[OffsetPixelHeigh + 3] << 24);
dreschpe 0:da1bf437cbc1 770 PixelWidth = BMP_Header[OffsetPixelWidth] + (BMP_Header[OffsetPixelWidth + 1] << 8) + (BMP_Header[OffsetPixelWidth + 2] << 16) + (BMP_Header[OffsetPixelWidth + 3] << 24);
dreschpe 0:da1bf437cbc1 771 if (PixelHeigh > height() + y || PixelWidth > width() + x) {
dreschpe 0:da1bf437cbc1 772 fclose(Image);
dreschpe 0:da1bf437cbc1 773 return(-3); // to big
dreschpe 0:da1bf437cbc1 774 }
dreschpe 0:da1bf437cbc1 775
dreschpe 0:da1bf437cbc1 776 start_data = BMP_Header[OffsetPixData] + (BMP_Header[OffsetPixData + 1] << 8) + (BMP_Header[OffsetPixData + 2] << 16) + (BMP_Header[OffsetPixData + 3] << 24);
dreschpe 0:da1bf437cbc1 777
dreschpe 0:da1bf437cbc1 778 line = (unsigned short *) malloc (2 * PixelWidth); // we need a buffer for a line
dreschpe 0:da1bf437cbc1 779 if (line == NULL) {
dreschpe 0:da1bf437cbc1 780 return(-4); // error no memory
dreschpe 0:da1bf437cbc1 781 }
dreschpe 0:da1bf437cbc1 782
dreschpe 0:da1bf437cbc1 783 // the bmp lines are padded to multiple of 4 bytes
dreschpe 0:da1bf437cbc1 784 padd = -1;
dreschpe 0:da1bf437cbc1 785 do {
dreschpe 0:da1bf437cbc1 786 padd ++;
dreschpe 0:da1bf437cbc1 787 } while ((PixelWidth * 2 + padd)%4 != 0);
dreschpe 0:da1bf437cbc1 788
dreschpe 0:da1bf437cbc1 789 window(x, y,PixelWidth ,PixelHeigh);
dreschpe 6:fe07ae8329f7 790 wr_cmd(0x2C); // send pixel
dreschpe 6:fe07ae8329f7 791 #ifndef TARGET_KL25Z // only 8 Bit SPI
dreschpe 6:fe07ae8329f7 792 _spi.format(16,3);
dreschpe 6:fe07ae8329f7 793 #endif // switch to 16 bit Mode 3
dreschpe 0:da1bf437cbc1 794 for (j = PixelHeigh - 1; j >= 0; j--) { //Lines bottom up
dreschpe 0:da1bf437cbc1 795 off = j * (PixelWidth * 2 + padd) + start_data; // start of line
dreschpe 0:da1bf437cbc1 796 fseek(Image, off ,SEEK_SET);
dreschpe 6:fe07ae8329f7 797 fread(line,1,PixelWidth * 2,Image); // read a line - slow
dreschpe 0:da1bf437cbc1 798 for (i = 0; i < PixelWidth; i++) { // copy pixel data to TFT
dreschpe 6:fe07ae8329f7 799 #ifndef TARGET_KL25Z // only 8 Bit SPI
dreschpe 0:da1bf437cbc1 800 _spi.write(line[i]); // one 16 bit pixel
dreschpe 6:fe07ae8329f7 801 #else
dreschpe 6:fe07ae8329f7 802 _spi.write(line[i] >> 8);
dreschpe 6:fe07ae8329f7 803 _spi.write(line[i]);
dreschpe 6:fe07ae8329f7 804 #endif
dreschpe 0:da1bf437cbc1 805 }
dreschpe 0:da1bf437cbc1 806 }
dreschpe 0:da1bf437cbc1 807 _cs = 1;
dreschpe 0:da1bf437cbc1 808 _spi.format(8,3);
dreschpe 0:da1bf437cbc1 809 free (line);
dreschpe 0:da1bf437cbc1 810 fclose(Image);
dreschpe 0:da1bf437cbc1 811 WindowMax();
dreschpe 0:da1bf437cbc1 812 return(1);
dreschpe 5:55aed13f2630 813 }