Forked from Peter Drescher lib, using always 16bit spi, init values for chinese red pcb, added read cmds and some mess here and there
Fork of SPI_TFT_ILI9341 by
Diff: SPI_TFT_ILI9341.cpp
- Revision:
- 8:a9d849c3dad0
- Parent:
- 7:4c30bea883bc
- Child:
- 9:1d3d41128693
--- a/SPI_TFT_ILI9341.cpp Sun Jan 26 20:54:21 2014 +0000 +++ b/SPI_TFT_ILI9341.cpp Wed Apr 23 18:20:33 2014 +0000 @@ -30,6 +30,7 @@ clk = sclk; orientation = 0; char_x = 0; + _reset = 0; tft_reset(); } @@ -53,19 +54,19 @@ wr_cmd(0x36); // MEMORY_ACCESS_CONTROL switch (orientation) { case 0: - _spi.write(0x48); + wr_8(0x48); break; case 1: - _spi.write(0x28); + wr_8(0x28); break; case 2: - _spi.write(0x88); + wr_8(0x88); break; case 3: - _spi.write(0xE8); + wr_8(0xE8); break; } - _cs = 1; + // _cs = 1; WindowMax(); } @@ -75,268 +76,321 @@ void SPI_TFT_ILI9341::wr_cmd(unsigned char cmd) { _dc = 0; - _cs = 0; + // _cs = 0; _spi.write(cmd); // mbed lib - _dc = 1; -} - - - -void SPI_TFT_ILI9341::wr_dat(unsigned char dat) -{ - _spi.write(dat); // mbed lib + // _cs = 1; } +void SPI_TFT_ILI9341::wr_8(unsigned char value) +{ + _dc = 1; + // _cs = 0; + _spi.write(value); // mbed lib + // _cs = 1; +} + +void SPI_TFT_ILI9341::wr_16(unsigned int value) +{ + _dc = 1; + // _cs = 0; + // #if defined TARGET_KL25Z // 8 Bit SPI + _spi.write(value >> 8); + _spi.write(value & 0xff); +// #else + // _spi.format(16,0); // switch to 16 bit Mode 3, but it takes some time + // _spi.write(value); // mbed lib +// _spi.format(8,0); +// #endif + // _cs = 1; +} + // the ILI9341 can read -char SPI_TFT_ILI9341::rd_byte(unsigned char cmd) +char SPI_TFT_ILI9341::wr_cmd_rd8(unsigned char cmd) { char r; _dc = 0; - _cs = 0; + // _cs = 0; _spi.write(cmd); // mbed lib - _cs = 1; - r = _spi.write(0xff); - _cs = 1; + _dc = 1; // fixed + r = _spi.write(0); + // _cs = 1; return(r); } - +// read 24 bit +int SPI_TFT_ILI9341::wr_cmd_rd24(unsigned char cmd) +{ + int d = 0; + char r; + _dc = 0; + // _cs = 0; +#if defined TARGET_NXP + d = cmd; + d = d << 1; + _spi.format(9,0); // we have to add a dummy clock cycle + _spi.write(d); + _spi.format(8,0); +#else + _spi.write(cmd); +#endif + _dc = 1; + r = _spi.write(0); + d = r; + r = _spi.write(0); + d = (d << 8) | r; + r = _spi.write(0); + d = (d << 8) | r; +#if !defined TARGET_NXP + // workaraound for not 9bit, get 1 bit more + r = _spi.write(0); + d = (d << 1) | (r>>7); + // we clocked 7 more bit so ILI waiting for 8th, resetting spi + _cs = 1; + _cs = 0; +#endif +// _cs = 0; + return(d); +} // read 32 bit -int SPI_TFT_ILI9341::rd_32(unsigned char cmd) +int SPI_TFT_ILI9341::wr_cmd_rd32(unsigned char cmd) { int d; char r; _dc = 0; - _cs = 0; + // _cs = 0; +#if defined TARGET_NXP d = cmd; d = d << 1; - _spi.format(9,3); // we have to add a dummy clock cycle + _spi.format(9,0); // we have to add a dummy clock cycle _spi.write(d); - _spi.format(8,3); + _spi.format(8,0); +#else + _spi.write(cmd); +#endif _dc = 1; - r = _spi.write(0xff); + r = _spi.write(0); d = r; - r = _spi.write(0xff); + r = _spi.write(0); d = (d << 8) | r; - r = _spi.write(0xff); + r = _spi.write(0); + d = (d << 8) | r; + r = _spi.write(0); d = (d << 8) | r; - r = _spi.write(0xff); - d = (d << 8) | r; - _cs = 1; +#if !defined TARGET_NXP + // workaraound for not 9bit, get 1 bit more + r = _spi.write(0); + d = (d << 1) | (r>>7); + // we clocked 7 more bit so ILI waiting for 8th, resetting spi + _cs = 1; + _cs = 0; +#endif +// _cs = 1; + return(d); +} +char SPI_TFT_ILI9341::Read_Register(char Addr, char xParameter) +{ + char data=0; + wr_cmd(0xd9); /* ext command */ + wr_8(0x10+xParameter); /* 0x11 is the first Parameter */ + data = wr_cmd_rd8(Addr); + return data; +} +int SPI_TFT_ILI9341::Read_ID4ext(void){ + char i; + char r; + int d=0; + for(i=0;i<3;i++) + { + r=Read_Register(0xd3,i+1); // D3 for ID4 + d = (d << 8) | r; + } + return(d); } -int SPI_TFT_ILI9341::Read_ID(void){ +// broken on 9341 +int SPI_TFT_ILI9341::Read_ID123(void){ int r; - r = rd_byte(0x0A); - r = rd_byte(0x0A); - r = rd_byte(0x0A); - r = rd_byte(0x0A); + r = wr_cmd_rd24(0x04); + return(r); +} +// broken on 9341 +int SPI_TFT_ILI9341::Read_ID4(void){ + int r; + r = wr_cmd_rd24(0xD3); + return(r); +} +int SPI_TFT_ILI9341::Read_STS(void){ + int r; + r = wr_cmd_rd32(0x09); return(r); } - -// Init code based on MI0283QT datasheet - +// HW reset void SPI_TFT_ILI9341::tft_reset() { - _spi.format(8,3); // 8 bit spi mode 3 + _spi.format(8,0); // 8 bit spi mode 3 _spi.frequency(10000000); // 10 Mhz SPI clock _cs = 1; // cs high _dc = 1; // dc high + _reset = 0; // display reset + wait_ms(50); + + _reset = 1; // end hardware reset + wait_ms(150); // or 5?!? + + _cs = 0; + + // wr_cmd(0x01); // SW reset + // wait_ms(150); // or 5?!? + tft_init_redPCBtm22(); +} - wait_us(50); - _reset = 1; // end hardware reset - wait_ms(5); + + // init for chinese 2.2" red PCB 1580005661C +void SPI_TFT_ILI9341::tft_init_redPCBtm22() +{ + /* Start Initial Sequence ----------------------------------------------------*/ + wr_cmd(0xCB); // POWER_ON_SEQ_CONTROL + wr_8(0x39); + wr_8(0x2C); + wr_8(0x00); + wr_8(0x34); + wr_8(0x02); - wr_cmd(0x01); // SW reset - wait_ms(5); - wr_cmd(0x28); // display off - - /* Start Initial Sequence ----------------------------------------------------*/ - wr_cmd(0xCF); - _spi.write(0x00); - _spi.write(0x83); - _spi.write(0x30); - _cs = 1; + wr_cmd(0xCF); // POWER_CONTROL_B + wr_8(0x00); + wr_8(0xC1); // Applic Notes 81, was 83, C1 enables PCEQ: PC and EQ operation for power saving + wr_8(0x30); + + wr_cmd(0xE8); // DRIVER_TIMING_CONTROL_A + wr_8(0x85); + wr_8(0x00); // AN 10, was 01 + wr_8(0x78); // AN 7A, was 79 + + wr_cmd(0xEA); // DRIVER_TIMING_CONTROL_B + wr_8(0x00); + wr_8(0x00); wr_cmd(0xED); - _spi.write(0x64); - _spi.write(0x03); - _spi.write(0x12); - _spi.write(0x81); - _cs = 1; - - wr_cmd(0xE8); - _spi.write(0x85); - _spi.write(0x01); - _spi.write(0x79); - _cs = 1; + wr_8(0x64); + wr_8(0x03); + wr_8(0x12); + wr_8(0x81); - wr_cmd(0xCB); - _spi.write(0x39); - _spi.write(0x2C); - _spi.write(0x00); - _spi.write(0x34); - _spi.write(0x02); - _cs = 1; - - wr_cmd(0xF7); - _spi.write(0x20); - _cs = 1; - - wr_cmd(0xEA); - _spi.write(0x00); - _spi.write(0x00); - _cs = 1; + wr_cmd(0xF7); // PUMP_RATIO_CONTROL + wr_8(0x20); wr_cmd(0xC0); // POWER_CONTROL_1 - _spi.write(0x26); - _cs = 1; - + wr_8(0x23); // AN 21, was 26 + wr_cmd(0xC1); // POWER_CONTROL_2 - _spi.write(0x11); - _cs = 1; + wr_8(0x10); // AN 11, was 11 wr_cmd(0xC5); // VCOM_CONTROL_1 - _spi.write(0x35); - _spi.write(0x3E); - _cs = 1; + wr_8(0x3E); // AN 3F, was 35 + wr_8(0x28); // AN 3C, was 3E wr_cmd(0xC7); // VCOM_CONTROL_2 - _spi.write(0xBE); - _cs = 1; + wr_8(0x86); // AN A7, was BE wr_cmd(0x36); // MEMORY_ACCESS_CONTROL - _spi.write(0x48); - _cs = 1; + wr_8(0x48); - wr_cmd(0x3A); // COLMOD_PIXEL_FORMAT_SET - _spi.write(0x55); // 16 bit pixel - _cs = 1; + wr_cmd(0x3A); // COLMOD_PIXEL_FORMAT_SET, not present in AN + wr_8(0x55); // 16 bit pixel wr_cmd(0xB1); // Frame Rate - _spi.write(0x00); - _spi.write(0x1B); - _cs = 1; + wr_8(0x00); + wr_8(0x18); // AN 1B, was 1B 1B=70hz + + wr_cmd(0xB6); // display function control, INTERESTING + wr_8(0x08); // AN 0A, was 0A + wr_8(0x82); // AN A2 + wr_8(0x27); // AN not present + // wr_8(0x00); // was present wr_cmd(0xF2); // Gamma Function Disable - _spi.write(0x08); - _cs = 1; + wr_8(0x00); // AN 00, was 08 wr_cmd(0x26); - _spi.write(0x01); // gamma set for curve 01/2/04/08 - _cs = 1; + wr_8(0x01); // gamma set for curve 01/2/04/08 wr_cmd(0xE0); // positive gamma correction - _spi.write(0x1F); - _spi.write(0x1A); - _spi.write(0x18); - _spi.write(0x0A); - _spi.write(0x0F); - _spi.write(0x06); - _spi.write(0x45); - _spi.write(0x87); - _spi.write(0x32); - _spi.write(0x0A); - _spi.write(0x07); - _spi.write(0x02); - _spi.write(0x07); - _spi.write(0x05); - _spi.write(0x00); - _cs = 1; + wr_8(0x0F); + wr_8(0x31); + wr_8(0x2B); + wr_8(0x0C); + wr_8(0x0E); + wr_8(0x08); + wr_8(0x4E); + wr_8(0xF1); + wr_8(0x37); + wr_8(0x07); + wr_8(0x10); + wr_8(0x03); + wr_8(0x0E); + wr_8(0x09); + wr_8(0x00); wr_cmd(0xE1); // negativ gamma correction - _spi.write(0x00); - _spi.write(0x25); - _spi.write(0x27); - _spi.write(0x05); - _spi.write(0x10); - _spi.write(0x09); - _spi.write(0x3A); - _spi.write(0x78); - _spi.write(0x4D); - _spi.write(0x05); - _spi.write(0x18); - _spi.write(0x0D); - _spi.write(0x38); - _spi.write(0x3A); - _spi.write(0x1F); - _cs = 1; + wr_8(0x00); + wr_8(0x0E); + wr_8(0x14); + wr_8(0x03); + wr_8(0x11); + wr_8(0x07); + wr_8(0x31); + wr_8(0xC1); + wr_8(0x48); + wr_8(0x08); + wr_8(0x0F); + wr_8(0x0C); + wr_8(0x31); + wr_8(0x36); + wr_8(0x0F); + + //wr_cmd(0x34); // tearing effect off + + //wr_cmd(0x35); // tearing effect on + + // wr_cmd(0xB7); // ENTRY_MODE_SET + // wr_8(0x07); + + wr_cmd(0x11); // sleep out + + wait_ms(150); + + wr_cmd(0x29); // display on + + wait_ms(150); WindowMax (); - //wr_cmd(0x34); // tearing effect off - //_cs = 1; - - //wr_cmd(0x35); // tearing effect on - //_cs = 1; - - wr_cmd(0xB7); // entry mode - _spi.write(0x07); - _cs = 1; - - wr_cmd(0xB6); // display function control - _spi.write(0x0A); - _spi.write(0x82); - _spi.write(0x27); - _spi.write(0x00); - _cs = 1; - - wr_cmd(0x11); // sleep out - _cs = 1; - - wait_ms(100); - - wr_cmd(0x29); // display on - _cs = 1; - - wait_ms(100); - } - - void SPI_TFT_ILI9341::pixel(int x, int y, int color) { wr_cmd(0x2A); - _spi.write(x >> 8); - _spi.write(x); - _cs = 1; - wr_cmd(0x2B); - _spi.write(y >> 8); - _spi.write(y); - _cs = 1; + wr_16(x); // set only start column, end colum have been set by windows funct + wr_cmd(0x2B); // set only start page + wr_16(y); wr_cmd(0x2C); // send pixel - #if defined TARGET_KL25Z // 8 Bit SPI - _spi.write(color >> 8); - _spi.write(color & 0xff); - #else - _spi.format(16,3); // switch to 16 bit Mode 3 - _spi.write(color); // Write D0..D15 - _spi.format(8,3); - #endif - _cs = 1; + wr_16(color); } void SPI_TFT_ILI9341::window (unsigned int x, unsigned int y, unsigned int w, unsigned int h) { wr_cmd(0x2A); - _spi.write(x >> 8); - _spi.write(x); - _spi.write((x+w-1) >> 8); - _spi.write(x+w-1); - - _cs = 1; + wr_16(x); + wr_16(x+w-1); + wr_cmd(0x2B); - _spi.write(y >> 8); - _spi.write(y); - _spi.write((y+h-1) >> 8); - _spi.write(y+h-1); - _cs = 1; + wr_16(y); + wr_16(y+h-1); } @@ -349,24 +403,14 @@ void SPI_TFT_ILI9341::cls (void) { - int pixel = ( width() * height()); + int pixels = ( width() * height()); WindowMax(); wr_cmd(0x2C); // send pixel - #if defined TARGET_KL25Z // 8 Bit SPI unsigned int i; - for (i = 0; i < ( width() * height()); i++){ - _spi.write(_background >> 8); - _spi.write(_background & 0xff); + for (i = 0; i < pixels; i++) + { + wr_16(_background); } - - #else - _spi.format(16,3); // switch to 16 bit Mode 3 - unsigned int i; - for (i = 0; i < ( width() * height()); i++) - _spi.write(_background); - _spi.format(8,3); - #endif - _cs = 1; } @@ -411,21 +455,9 @@ w = x1 - x0 + 1; window(x0,y,w,1); wr_cmd(0x2C); // send pixel - #if defined TARGET_KL25Z // 8 Bit SPI - int j; - for (j=0; j<w; j++) { - _spi.write(color >> 8); - _spi.write(color & 0xff); - } - #else - _spi.format(16,3); // switch to 16 bit Mode 3 - int j; - for (j=0; j<w; j++) { - _spi.write(color); + for (int j=0; j<w; j++) { + wr_16(color); } - _spi.format(8,3); - #endif - _cs = 1; WindowMax(); return; } @@ -436,19 +468,9 @@ h = y1 - y0 + 1; window(x,y0,1,h); wr_cmd(0x2C); // send pixel - #if defined TARGET_KL25Z // 8 Bit SPI for (int y=0; y<h; y++) { - _spi.write(color >> 8); - _spi.write(color & 0xff); - } - #else - _spi.format(16,3); // switch to 16 bit Mode 3 - for (int y=0; y<h; y++) { - _spi.write(color); + wr_16(color); } - _spi.format(8,3); - #endif - _cs = 1; WindowMax(); return; } @@ -549,25 +571,28 @@ void SPI_TFT_ILI9341::fillrect(int x0, int y0, int x1, int y1, int color) { - + int tmp; + if(x0 > x1) + { + tmp=x0; // swap them + x0=x1; + x1=tmp; + } + if(y0 > y1) + { + tmp=y0; // swap them + y0=y1; + y1=tmp; + } + int h = y1 - y0 + 1; int w = x1 - x0 + 1; - int pixel = h * w; + int pixels = h * w; window(x0,y0,w,h); wr_cmd(0x2C); // send pixel - #if defined TARGET_KL25Z // 8 Bit SPI - for (int p=0; p<pixel; p++) { - _spi.write(color >> 8); - _spi.write(color & 0xff); + for (int p=0; p<pixels; p++) { + wr_16(color); } - #else - _spi.format(16,3); // switch to 16 bit Mode 3 - for (int p=0; p<pixel; p++) { - _spi.write(color); - } - _spi.format(8,3); - #endif - _cs = 1; WindowMax(); return; } @@ -633,36 +658,20 @@ } window(char_x, char_y,hor,vert); // char box wr_cmd(0x2C); // send pixel - #ifndef TARGET_KL25Z // 16 Bit SPI - _spi.format(16,3); - #endif // switch to 16 bit Mode 3 zeichen = &font[((c -32) * offset) + 4]; // start of char bitmap w = zeichen[0]; // width of actual char for (j=0; j<vert; j++) { // vert line for (i=0; i<hor; i++) { // horz line z = zeichen[bpl * i + ((j & 0xF8) >> 3)+1]; b = 1 << (j & 0x07); - if (( z & b ) == 0x00) { - #ifndef TARGET_KL25Z // 16 Bit SPI - _spi.write(_background); - #else - _spi.write(_background >> 8); - _spi.write(_background & 0xff); - #endif + if (( z & b ) == 0x00) { + wr_16(_background); } else { - #ifndef TARGET_KL25Z // 16 Bit SPI - _spi.write(_foreground); - #else - _spi.write(_foreground >> 8); - _spi.write(_foreground & 0xff); - #endif + wr_16(_foreground); } } } - _cs = 1; - #ifndef TARGET_KL25Z // 16 Bit SPI - _spi.format(8,3); - #endif + WindowMax(); if ((w + 2) < hor) { // x offset to next char char_x += w + 2; @@ -681,11 +690,7 @@ { unsigned int j; int padd; - unsigned short *bitmap_ptr = (unsigned short *)bitmap; - #if defined TARGET_KL25Z // 8 Bit SPI - unsigned short pix_temp; - #endif - + unsigned short *bitmap_ptr = (unsigned short *)bitmap; unsigned int i; // the lines are padded to multiple of 4 bytes in a bitmap @@ -696,28 +701,14 @@ window(x, y, w, h); bitmap_ptr += ((h - 1)* (w + padd)); wr_cmd(0x2C); // send pixel - #ifndef TARGET_KL25Z // 16 Bit SPI - _spi.format(16,3); - #endif // switch to 16 bit Mode 3 for (j = 0; j < h; j++) { //Lines for (i = 0; i < w; i++) { // one line - #if defined TARGET_KL25Z // 8 Bit SPI - pix_temp = *bitmap_ptr; - _spi.write(pix_temp >> 8); - _spi.write(pix_temp); + wr_16(*bitmap_ptr); bitmap_ptr++; - #else - _spi.write(*bitmap_ptr); // one line - bitmap_ptr++; - #endif } bitmap_ptr -= 2*w; bitmap_ptr -= padd; } - _cs = 1; - #ifndef TARGET_KL25Z // 16 Bit SPI - _spi.format(8,3); - #endif WindowMax(); } @@ -788,24 +779,14 @@ window(x, y,PixelWidth ,PixelHeigh); wr_cmd(0x2C); // send pixel - #ifndef TARGET_KL25Z // only 8 Bit SPI - _spi.format(16,3); - #endif // switch to 16 bit Mode 3 for (j = PixelHeigh - 1; j >= 0; j--) { //Lines bottom up off = j * (PixelWidth * 2 + padd) + start_data; // start of line fseek(Image, off ,SEEK_SET); fread(line,1,PixelWidth * 2,Image); // read a line - slow for (i = 0; i < PixelWidth; i++) { // copy pixel data to TFT - #ifndef TARGET_KL25Z // only 8 Bit SPI - _spi.write(line[i]); // one 16 bit pixel - #else - _spi.write(line[i] >> 8); - _spi.write(line[i]); - #endif + wr_16(line[i]); // one 16 bit pixel } } - _cs = 1; - _spi.format(8,3); free (line); fclose(Image); WindowMax();