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 16:51:27 2014 +0000
Revision:
13:b2b3e5430f81
add fast LPC1768 version

Who changed what in which revision?

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