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
Parent:
12:98cc5c193ecd
add fast LPC1768 version

Who changed what in which revision?

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