TFT driver for ILI9341. I imported this library from Seeed-Studio-28-TFT-Touch-Shield-V20.

Dependents:   TFT_sdcard TS_Eyes Tokei AfficheurTFTAdafruit ... more

Fork of SPI_TFT_ILI9341 by Components

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers SPI_TFT_ILI9341.cpp Source File

SPI_TFT_ILI9341.cpp

00001 /* mbed library for 240*320 pixel display TFT based on ILI9341 LCD Controller
00002  * Copyright (c) 2013 Peter Drescher - DC2PD
00003  *
00004  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00005  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00006  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
00007  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00008  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
00009  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
00010  * THE SOFTWARE.
00011  */
00012  
00013 // 12.06.13 fork from SPI_TFT code because controller is different ...
00014 // 14.07.13 Test with real display and bugfix 
00015 // 18.10.13 Better Circle function from Michael Ammann
00016 // 22.10.13 Fixes for Kinetis Board - 8 bit spi
00017 
00018 #include "SPI_TFT_ILI9341.h"
00019 #include "mbed.h"
00020 
00021 #define BPP         16                  // Bits per pixel    
00022             
00023 
00024 //extern Serial pc;
00025 //extern DigitalOut xx;     // debug !!
00026 
00027 SPI_TFT_ILI9341::SPI_TFT_ILI9341(PinName mosi, PinName miso, PinName sclk, PinName cs, PinName reset, PinName dc, const char *name)
00028     : GraphicsDisplay(name), _spi(mosi, miso, sclk), _cs(cs), _dc(dc)
00029 {
00030     orientation = 0;
00031     char_x = 0;
00032     _reset = reset;
00033     tft_reset();
00034 }
00035 
00036 int SPI_TFT_ILI9341::width()
00037 {
00038     if (orientation == 0 || orientation == 2) return 240;
00039     else return 320;
00040 }
00041 
00042 
00043 int SPI_TFT_ILI9341::height()
00044 {
00045     if (orientation == 0 || orientation == 2) return 320;
00046     else return 240;
00047 }
00048 
00049 
00050 void SPI_TFT_ILI9341::set_orientation(unsigned int o)
00051 {
00052     orientation = o;
00053     wr_cmd(0x36);                     // MEMORY_ACCESS_CONTROL
00054     switch (orientation) {
00055         case 0:
00056             _spi.write(0x48);
00057             break;
00058         case 1:
00059             _spi.write(0x28);
00060             break;
00061         case 2:
00062             _spi.write(0x88);
00063             break;
00064         case 3:
00065             _spi.write(0xE8);
00066             break;
00067     }
00068     _cs = 1; 
00069     WindowMax();
00070 } 
00071 
00072 
00073 // write command to tft register
00074 
00075 void SPI_TFT_ILI9341::wr_cmd(unsigned char cmd)
00076 {
00077     _dc = 0;
00078     _cs = 0;
00079     _spi.write(cmd);      // mbed lib
00080     _dc = 1;
00081 }
00082 
00083 
00084 
00085 void SPI_TFT_ILI9341::wr_dat(unsigned char dat)
00086 {
00087    _spi.write(dat);      // mbed lib
00088 }
00089 
00090 
00091 
00092 // the ILI9341 can read - has to be implemented later
00093 // A read will return 0 at the moment
00094 
00095 //unsigned short SPI_TFT_ILI9341::rd_dat (void)
00096 //{
00097 //    unsigned short val = 0;
00098 
00099     //val = _spi.write(0x73ff);                /* Dummy read 1           */
00100     //val   = _spi.write(0x0000);              /* Read D8..D15           */
00101 //    return (val);
00102 //}
00103 
00104 
00105 
00106 // Init code based on MI0283QT datasheet
00107 
00108 void SPI_TFT_ILI9341::tft_reset()
00109 {
00110     _spi.format(8,3);                  // 8 bit spi mode 3
00111   _spi.frequency(10000000);          // 10 Mhz SPI clock
00112  //   _spi.frequency(1000000) ;
00113     _cs = 1;                           // cs high
00114     _dc = 1;                           // dc high 
00115     if (_reset != NC)
00116     {
00117         DigitalOut rst(_reset);
00118         rst = 0;                       // display reset
00119         wait_us(50);
00120         rst = 1;                       // end hardware reset
00121     }
00122     wait_ms(5);
00123      
00124     wr_cmd(0x01);                     // SW reset  
00125     wait_ms(5);
00126     wr_cmd(0x28);                     // display off  
00127 
00128     /* Start Initial Sequence ----------------------------------------------------*/
00129      wr_cmd(0xCF);                     
00130      _spi.write(0x00);
00131      _spi.write(0x83);
00132      _spi.write(0x30);
00133      _cs = 1;
00134      
00135      wr_cmd(0xED);                     
00136      _spi.write(0x64);
00137      _spi.write(0x03);
00138      _spi.write(0x12);
00139      _spi.write(0x81);
00140      _cs = 1;
00141      
00142      wr_cmd(0xE8);                     
00143      _spi.write(0x85);
00144      _spi.write(0x01);
00145      _spi.write(0x79);
00146      _cs = 1;
00147      
00148      wr_cmd(0xCB);                     
00149      _spi.write(0x39);
00150      _spi.write(0x2C);
00151      _spi.write(0x00);
00152      _spi.write(0x34);
00153      _spi.write(0x02);
00154      _cs = 1;
00155            
00156      wr_cmd(0xF7);                     
00157      _spi.write(0x20);
00158      _cs = 1;
00159            
00160      wr_cmd(0xEA);                     
00161      _spi.write(0x00);
00162      _spi.write(0x00);
00163      _cs = 1;
00164      
00165      wr_cmd(0xC0);                     // POWER_CONTROL_1
00166      _spi.write(0x26);
00167      _cs = 1;
00168  
00169      wr_cmd(0xC1);                     // POWER_CONTROL_2
00170      _spi.write(0x11);
00171      _cs = 1;
00172      
00173      wr_cmd(0xC5);                     // VCOM_CONTROL_1
00174      _spi.write(0x35);
00175      _spi.write(0x3E);
00176      _cs = 1;
00177      
00178      wr_cmd(0xC7);                     // VCOM_CONTROL_2
00179      _spi.write(0xBE);
00180      _cs = 1; 
00181      
00182      wr_cmd(0x36);                     // MEMORY_ACCESS_CONTROL
00183      _spi.write(0x48);
00184      _cs = 1; 
00185      
00186      wr_cmd(0x3A);                     // COLMOD_PIXEL_FORMAT_SET
00187      _spi.write(0x55);                 // 16 bit pixel 
00188      _cs = 1;
00189      
00190      wr_cmd(0xB1);                     // Frame Rate
00191      _spi.write(0x00);
00192      _spi.write(0x1B);               
00193      _cs = 1;
00194      
00195      wr_cmd(0xF2);                     // Gamma Function Disable
00196      _spi.write(0x08);
00197      _cs = 1; 
00198      
00199      wr_cmd(0x26);                     
00200      _spi.write(0x01);                 // gamma set for curve 01/2/04/08
00201      _cs = 1; 
00202      
00203      wr_cmd(0xE0);                     // positive gamma correction
00204      _spi.write(0x1F); 
00205      _spi.write(0x1A); 
00206      _spi.write(0x18); 
00207      _spi.write(0x0A); 
00208      _spi.write(0x0F); 
00209      _spi.write(0x06); 
00210      _spi.write(0x45); 
00211      _spi.write(0x87); 
00212      _spi.write(0x32); 
00213      _spi.write(0x0A); 
00214      _spi.write(0x07); 
00215      _spi.write(0x02); 
00216      _spi.write(0x07);
00217      _spi.write(0x05); 
00218      _spi.write(0x00);
00219      _cs = 1;
00220      
00221      wr_cmd(0xE1);                     // negativ gamma correction
00222      _spi.write(0x00); 
00223      _spi.write(0x25); 
00224      _spi.write(0x27); 
00225      _spi.write(0x05); 
00226      _spi.write(0x10); 
00227      _spi.write(0x09); 
00228      _spi.write(0x3A); 
00229      _spi.write(0x78); 
00230      _spi.write(0x4D); 
00231      _spi.write(0x05); 
00232      _spi.write(0x18); 
00233      _spi.write(0x0D); 
00234      _spi.write(0x38);
00235      _spi.write(0x3A); 
00236      _spi.write(0x1F);
00237      _cs = 1;
00238      
00239      WindowMax ();
00240      
00241      //wr_cmd(0x34);                     // tearing effect off
00242      //_cs = 1;
00243      
00244      //wr_cmd(0x35);                     // tearing effect on
00245      //_cs = 1;
00246       
00247      wr_cmd(0xB7);                       // entry mode
00248      _spi.write(0x07);
00249      _cs = 1;
00250      
00251      wr_cmd(0xB6);                       // display function control
00252      _spi.write(0x0A);
00253      _spi.write(0x82);
00254      _spi.write(0x27);
00255      _spi.write(0x00);
00256      _cs = 1;
00257      
00258      wr_cmd(0x11);                     // sleep out
00259      _cs = 1;
00260      
00261      wait_ms(100);
00262      
00263      wr_cmd(0x29);                     // display on
00264      _cs = 1;
00265      
00266      wait_ms(100);
00267      
00268  }
00269 
00270 
00271 void SPI_TFT_ILI9341::pixel(int x, int y, int color)
00272 {
00273     wr_cmd(0x2A);
00274     _spi.write(x >> 8);
00275     _spi.write(x);
00276     _cs = 1;
00277     wr_cmd(0x2B);
00278     _spi.write(y >> 8);
00279     _spi.write(y);
00280     _cs = 1;
00281     wr_cmd(0x2C);  // send pixel
00282     #if defined TARGET_KL25Z  // 8 Bit SPI
00283     _spi.write(color >> 8);
00284     _spi.write(color & 0xff);
00285     #else 
00286     _spi.format(16,3);                            // switch to 16 bit Mode 3
00287     _spi.write(color);                              // Write D0..D15
00288     _spi.format(8,3);
00289     #endif
00290     _cs = 1;
00291 }
00292 
00293 
00294 void SPI_TFT_ILI9341::window (unsigned int x, unsigned int y, unsigned int w, unsigned int h)
00295 {
00296     wr_cmd(0x2A);
00297     _spi.write(x >> 8);
00298     _spi.write(x);
00299     _spi.write((x+w-1) >> 8);
00300     _spi.write(x+w-1);
00301     
00302     _cs = 1;
00303     wr_cmd(0x2B);
00304     _spi.write(y >> 8);
00305     _spi.write(y);
00306     _spi.write((y+h-1) >> 8);
00307     _spi.write(y+h-1);
00308     _cs = 1;
00309 }
00310 
00311 
00312 void SPI_TFT_ILI9341::WindowMax (void)
00313 {
00314     window (0, 0, width(),  height());
00315 }
00316 
00317 
00318 
00319 void SPI_TFT_ILI9341::cls (void)
00320 {
00321     int pixel = ( width() * height());
00322 //    tft_reset() ; // effective but may be too much
00323     WindowMax();
00324     wr_cmd(0x2C);  // send pixel
00325     #if defined TARGET_KL25Z  // 8 Bit SPI
00326     unsigned int i;
00327     for (i = 0; i < ( width() * height()); i++){
00328  //   for (i = 0 ; i < pixel ; i++ ) {
00329         _spi.write(_background >> 8);
00330         _spi.write(_background & 0xff);
00331         }
00332     
00333     #else 
00334     _spi.format(16,3);                            // switch to 16 bit Mode 3
00335     unsigned int i;
00336     for (i = 0; i < ( width() * height()); i++)
00337  //   for (i = 0 ; i < pixel ; i++ ) 
00338         _spi.write(_background);
00339     _spi.format(8,3);    
00340     #endif                         
00341     _cs = 1; 
00342 }
00343 
00344 
00345 void SPI_TFT_ILI9341::circle(int x0, int y0, int r, int color)
00346 {
00347 
00348     int x = -r, y = 0, err = 2-2*r, e2;
00349     do {
00350         pixel(x0-x, y0+y,color);
00351         pixel(x0+x, y0+y,color);
00352         pixel(x0+x, y0-y,color);
00353         pixel(x0-x, y0-y,color);
00354         e2 = err;
00355         if (e2 <= y) {
00356             err += ++y*2+1;
00357             if (-x == y && e2 <= x) e2 = 0;
00358         }
00359         if (e2 > x) err += ++x*2+1;
00360     } while (x <= 0);
00361 
00362 }
00363 
00364 void SPI_TFT_ILI9341::fillcircle(int x0, int y0, int r, int color)
00365 {
00366     int x = -r, y = 0, err = 2-2*r, e2;
00367     do {
00368         vline(x0-x, y0-y, y0+y, color);
00369         vline(x0+x, y0-y, y0+y, color);
00370         e2 = err;
00371         if (e2 <= y) {
00372             err += ++y*2+1;
00373             if (-x == y && e2 <= x) e2 = 0;
00374         }
00375         if (e2 > x) err += ++x*2+1;
00376     } while (x <= 0);
00377 }
00378 
00379 
00380 void SPI_TFT_ILI9341::hline(int x0, int x1, int y, int color)
00381 {
00382     int w;
00383     w = x1 - x0 + 1;
00384     window(x0,y,w,1);
00385     wr_cmd(0x2C);  // send pixel
00386     #if defined TARGET_KL25Z  // 8 Bit SPI
00387     int j;
00388     for (j=0; j<w; j++) {
00389         _spi.write(color >> 8);
00390         _spi.write(color & 0xff);
00391     } 
00392     #else 
00393     _spi.format(16,3);                            // switch to 16 bit Mode 3
00394     int j;
00395     for (j=0; j<w; j++) {
00396         _spi.write(color);
00397     }
00398     _spi.format(8,3);
00399     #endif
00400     _cs = 1;
00401     WindowMax();
00402     return;
00403 }
00404 
00405 void SPI_TFT_ILI9341::vline(int x, int y0, int y1, int color)
00406 {
00407     int h;
00408     h = y1 - y0 + 1;
00409     window(x,y0,1,h);
00410     wr_cmd(0x2C);  // send pixel
00411     #if defined TARGET_KL25Z  // 8 Bit SPI
00412     for (int y=0; y<h; y++) {
00413         _spi.write(color >> 8);
00414         _spi.write(color & 0xff);
00415     } 
00416     #else 
00417     _spi.format(16,3);                            // switch to 16 bit Mode 3
00418     for (int y=0; y<h; y++) {
00419         _spi.write(color);
00420     }
00421     _spi.format(8,3);
00422     #endif
00423     _cs = 1;
00424     WindowMax();
00425     return;
00426 }
00427 
00428 
00429 
00430 void SPI_TFT_ILI9341::line(int x0, int y0, int x1, int y1, int color)
00431 {
00432     //WindowMax();
00433     int   dx = 0, dy = 0;
00434     int   dx_sym = 0, dy_sym = 0;
00435     int   dx_x2 = 0, dy_x2 = 0;
00436     int   di = 0;
00437 
00438     dx = x1-x0;
00439     dy = y1-y0;
00440 
00441     if (dx == 0) {        /* vertical line */
00442         if (y1 > y0) vline(x0,y0,y1,color);
00443         else vline(x0,y1,y0,color);
00444         return;
00445     }
00446 
00447     if (dx > 0) {
00448         dx_sym = 1;
00449     } else {
00450         dx_sym = -1;
00451     }
00452     if (dy == 0) {        /* horizontal line */
00453         if (x1 > x0) hline(x0,x1,y0,color);
00454         else  hline(x1,x0,y0,color);
00455         return;
00456     }
00457 
00458     if (dy > 0) {
00459         dy_sym = 1;
00460     } else {
00461         dy_sym = -1;
00462     }
00463 
00464     dx = dx_sym*dx;
00465     dy = dy_sym*dy;
00466 
00467     dx_x2 = dx*2;
00468     dy_x2 = dy*2;
00469 
00470     if (dx >= dy) {
00471         di = dy_x2 - dx;
00472         while (x0 != x1) {
00473 
00474             pixel(x0, y0, color);
00475             x0 += dx_sym;
00476             if (di<0) {
00477                 di += dy_x2;
00478             } else {
00479                 di += dy_x2 - dx_x2;
00480                 y0 += dy_sym;
00481             }
00482         }
00483         pixel(x0, y0, color);
00484     } else {
00485         di = dx_x2 - dy;
00486         while (y0 != y1) {
00487             pixel(x0, y0, color);
00488             y0 += dy_sym;
00489             if (di < 0) {
00490                 di += dx_x2;
00491             } else {
00492                 di += dx_x2 - dy_x2;
00493                 x0 += dx_sym;
00494             }
00495         }
00496         pixel(x0, y0, color);
00497     }
00498     return;
00499 }
00500 
00501 
00502 void SPI_TFT_ILI9341::rect(int x0, int y0, int x1, int y1, int color)
00503 {
00504 
00505     if (x1 > x0) hline(x0,x1,y0,color);
00506     else  hline(x1,x0,y0,color);
00507 
00508     if (y1 > y0) vline(x0,y0,y1,color);
00509     else vline(x0,y1,y0,color);
00510 
00511     if (x1 > x0) hline(x0,x1,y1,color);
00512     else  hline(x1,x0,y1,color);
00513 
00514     if (y1 > y0) vline(x1,y0,y1,color);
00515     else vline(x1,y1,y0,color);
00516 
00517     return;
00518 }
00519 
00520 
00521 
00522 void SPI_TFT_ILI9341::fillrect(int x0, int y0, int x1, int y1, int color)
00523 {
00524 
00525     int h = y1 - y0 + 1;
00526     int w = x1 - x0 + 1;
00527     int pixel = h * w;
00528     window(x0,y0,w,h);
00529     wr_cmd(0x2C);  // send pixel 
00530     #if defined TARGET_KL25Z  // 8 Bit SPI
00531     for (int p=0; p<pixel; p++) {
00532         _spi.write(color >> 8);
00533         _spi.write(color & 0xff);
00534     }
00535    #else
00536     _spi.format(16,3);                            // switch to 16 bit Mode 3
00537     for (int p=0; p<pixel; p++) {
00538         _spi.write(color);
00539     }
00540     _spi.format(8,3);
00541     #endif
00542     _cs = 1;
00543     WindowMax();
00544     return;
00545 }
00546 
00547 
00548 void SPI_TFT_ILI9341::locate(int x, int y)
00549 {
00550     char_x = x;
00551     char_y = y;
00552 }
00553 
00554 
00555 
00556 int SPI_TFT_ILI9341::columns()
00557 {
00558     return width() / font[1];
00559 }
00560 
00561 
00562 
00563 int SPI_TFT_ILI9341::rows()
00564 {
00565     return height() / font[2];
00566 }
00567 
00568 
00569 
00570 int SPI_TFT_ILI9341::_putc(int value)
00571 {
00572     if (value == '\n') {    // new line
00573         char_x = 0;
00574         char_y = char_y + font[2];
00575         if (char_y >= height() - font[2]) {
00576             char_y = 0;
00577         }
00578     } else {
00579         character(char_x, char_y, value);
00580     }
00581     return value;
00582 }
00583 
00584 
00585 void SPI_TFT_ILI9341::character(int x, int y, int c)
00586 {
00587     unsigned int hor,vert,offset,bpl,j,i,b;
00588     unsigned char* zeichen;
00589     unsigned char z,w;
00590 
00591     if ((c < 31) || (c > 127)) return;   // test char range
00592 
00593     // read font parameter from start of array
00594     offset = font[0];                    // bytes / char
00595     hor = font[1];                       // get hor size of font
00596     vert = font[2];                      // get vert size of font
00597     bpl = font[3];                       // bytes per line
00598 
00599     if (char_x + hor > width()) {
00600         char_x = 0;
00601         char_y = char_y + vert;
00602         if (char_y >= height() - font[2]) {
00603             char_y = 0;
00604         }
00605     }
00606     window(char_x, char_y,hor,vert); // char box
00607     wr_cmd(0x2C);  // send pixel
00608     #ifndef TARGET_KL25Z  // 16 Bit SPI 
00609     _spi.format(16,3);   
00610     #endif                         // switch to 16 bit Mode 3
00611     zeichen = &font[((c -32) * offset) + 4]; // start of char bitmap
00612     w = zeichen[0];                          // width of actual char
00613      for (j=0; j<vert; j++) {  //  vert line
00614         for (i=0; i<hor; i++) {   //  horz line
00615             z =  zeichen[bpl * i + ((j & 0xF8) >> 3)+1];
00616             b = 1 << (j & 0x07);
00617             if (( z & b ) == 0x00) {
00618                #ifndef TARGET_KL25Z  // 16 Bit SPI 
00619                 _spi.write(_background);
00620                #else
00621                 _spi.write(_background >> 8);
00622                 _spi.write(_background & 0xff);
00623                 #endif
00624             } else {
00625                 #ifndef TARGET_KL25Z  // 16 Bit SPI
00626                 _spi.write(_foreground);
00627                 #else
00628                 _spi.write(_foreground >> 8);
00629                 _spi.write(_foreground & 0xff);
00630                 #endif
00631             }
00632         }
00633     }
00634     _cs = 1;
00635     #ifndef TARGET_KL25Z  // 16 Bit SPI
00636     _spi.format(8,3);
00637     #endif
00638     WindowMax();
00639     if ((w + 2) < hor) {                   // x offset to next char
00640         char_x += w + 2;
00641     } else char_x += hor;
00642 }
00643 
00644 
00645 void SPI_TFT_ILI9341::set_font(unsigned char* f)
00646 {
00647     font = f;
00648 }
00649 
00650 
00651 
00652 void SPI_TFT_ILI9341::Bitmap(unsigned int x, unsigned int y, unsigned int w, unsigned int h,unsigned char *bitmap)
00653 {
00654     unsigned int  j;
00655     int padd;
00656     unsigned short *bitmap_ptr = (unsigned short *)bitmap;
00657     #if defined TARGET_KL25Z  // 8 Bit SPI
00658         unsigned short pix_temp;
00659     #endif
00660     
00661     unsigned int i;
00662     
00663     // the lines are padded to multiple of 4 bytes in a bitmap
00664     padd = -1;
00665     do {
00666         padd ++;
00667     } while (2*(w + padd)%4 != 0);
00668     window(x, y, w, h);
00669     bitmap_ptr += ((h - 1)* (w + padd));
00670     wr_cmd(0x2C);  // send pixel
00671     #ifndef TARGET_KL25Z  // 16 Bit SPI 
00672     _spi.format(16,3);
00673     #endif                            // switch to 16 bit Mode 3
00674     for (j = 0; j < h; j++) {         //Lines
00675         for (i = 0; i < w; i++) {     // one line
00676             #if defined TARGET_KL25Z  // 8 Bit SPI
00677                 pix_temp = *bitmap_ptr;
00678                 _spi.write(pix_temp >> 8);
00679                 _spi.write(pix_temp);
00680                 bitmap_ptr++;
00681             #else
00682                 _spi.write(*bitmap_ptr);    // one line
00683                 bitmap_ptr++;
00684             #endif
00685         }
00686         bitmap_ptr -= 2*w;
00687         bitmap_ptr -= padd;
00688     }
00689     _cs = 1;
00690     #ifndef TARGET_KL25Z  // 16 Bit SPI 
00691     _spi.format(8,3);
00692     #endif
00693     WindowMax();
00694 }
00695 
00696 
00697 // local filesystem is not implemented in kinetis board
00698 #if DEVICE_LOCALFILESYSTEM
00699 
00700 int SPI_TFT_ILI9341::BMP_16(unsigned int x, unsigned int y, const char *Name_BMP)
00701 {
00702 
00703 #define OffsetPixelWidth    18
00704 #define OffsetPixelHeigh    22
00705 #define OffsetFileSize      34
00706 #define OffsetPixData       10
00707 #define OffsetBPP           28
00708 
00709     char filename[50];
00710     unsigned char BMP_Header[54];
00711     unsigned short BPP_t;
00712     unsigned int PixelWidth,PixelHeigh,start_data;
00713     unsigned int    i,off;
00714     int padd,j;
00715     unsigned short *line;
00716 
00717     // get the filename
00718     LocalFileSystem local("local");
00719     sprintf(&filename[0],"/local/");
00720     i=7;
00721     while (*Name_BMP!='\0') {
00722         filename[i++]=*Name_BMP++;
00723     }
00724 
00725     fprintf(stderr, "filename : %s \n\r",filename);
00726 
00727     FILE *Image = fopen((const char *)&filename[0], "rb");  // open the bmp file
00728     if (!Image) {
00729         return(0);      // error file not found !
00730     }
00731 
00732     fread(&BMP_Header[0],1,54,Image);      // get the BMP Header
00733 
00734     if (BMP_Header[0] != 0x42 || BMP_Header[1] != 0x4D) {  // check magic byte
00735         fclose(Image);
00736         return(-1);     // error no BMP file
00737     }
00738 
00739     BPP_t = BMP_Header[OffsetBPP] + (BMP_Header[OffsetBPP + 1] << 8);
00740     if (BPP_t != 0x0010) {
00741         fclose(Image);
00742         return(-2);     // error no 16 bit BMP
00743     }
00744 
00745     PixelHeigh = BMP_Header[OffsetPixelHeigh] + (BMP_Header[OffsetPixelHeigh + 1] << 8) + (BMP_Header[OffsetPixelHeigh + 2] << 16) + (BMP_Header[OffsetPixelHeigh + 3] << 24);
00746     PixelWidth = BMP_Header[OffsetPixelWidth] + (BMP_Header[OffsetPixelWidth + 1] << 8) + (BMP_Header[OffsetPixelWidth + 2] << 16) + (BMP_Header[OffsetPixelWidth + 3] << 24);
00747     if (PixelHeigh > height() + y || PixelWidth > width() + x) {
00748         fclose(Image);
00749         return(-3);      // to big
00750     }
00751 
00752     start_data = BMP_Header[OffsetPixData] + (BMP_Header[OffsetPixData + 1] << 8) + (BMP_Header[OffsetPixData + 2] << 16) + (BMP_Header[OffsetPixData + 3] << 24);
00753 
00754     line = (unsigned short *) malloc (2 * PixelWidth); // we need a buffer for a line
00755     if (line == NULL) {
00756         return(-4);         // error no memory
00757     }
00758 
00759     // the bmp lines are padded to multiple of 4 bytes
00760     padd = -1;
00761     do {
00762         padd ++;
00763     } while ((PixelWidth * 2 + padd)%4 != 0);
00764 
00765 
00766 //fseek(Image, 70 ,SEEK_SET);
00767     window(x, y,PixelWidth ,PixelHeigh);
00768     wr_cmd(0x2C);  // send pixel 
00769     _spi.format(16,3);                            // switch to 16 bit Mode 3
00770     for (j = PixelHeigh - 1; j >= 0; j--) {               //Lines bottom up
00771         off = j * (PixelWidth  * 2 + padd) + start_data;   // start of line
00772         fseek(Image, off ,SEEK_SET);
00773         fread(line,1,PixelWidth * 2,Image);       // read a line - slow !
00774         for (i = 0; i < PixelWidth; i++) {        // copy pixel data to TFT
00775             _spi.write(line[i]);                  // one 16 bit pixel
00776         } 
00777      }
00778     _cs = 1;
00779     _spi.format(8,3);
00780     free (line);
00781     fclose(Image);
00782     WindowMax();
00783     return(1);
00784 }
00785 #endif