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:
Wed Jun 25 07:54:58 2014 +0000
Revision:
12:98cc5c193ecd
Parent:
11:59eca2723ec5
Child:
13:b2b3e5430f81
Add fast Version for Nucleo F103

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