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:
mazgch
Date:
Fri Oct 18 08:10:41 2013 +0000
Revision:
3:3d7298360e45
Parent:
2:0a16083193a4
Child:
4:f018e272220b
better circle functions

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