Chinese module HY-1.8 SPI TFT lcd Display library.

Dependencies:   BurstSPI

Dependents:   KL25Z_DCF77_HY-1_8LCD

Fork of HY-1_8TFT_ST7735 by Paul Staron

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers ST7735_TFT.cpp Source File

ST7735_TFT.cpp

00001  //  ST7735 8 Bit SPI Library
00002 
00003 
00004 #include "ST7735_TFT.h"
00005 #include "mbed.h"
00006 
00007 #define BPP         16                  // Bits per pixel                
00008 
00009 ST7735_TFT::ST7735_TFT(PinName mosi, PinName miso, PinName sclk, PinName cs, PinName rs, PinName reset, const char *name)
00010         : GraphicsDisplay(name),_spi(mosi, miso, sclk), _cs(cs), _rs(rs), _reset(reset)
00011          {
00012     tft_reset();
00013     orientation = 2;
00014     char_x = 0;
00015 }
00016 int ST7735_TFT::width() {
00017     if (orientation == 0 || orientation == 2) return 128;
00018     else return 160; 
00019 }
00020 int ST7735_TFT::height() {
00021     if (orientation == 0 || orientation == 2) return 160;
00022     else return 128; 
00023 }
00024 void ST7735_TFT::set_orientation(unsigned int o) {
00025     orientation = o;
00026     switch (orientation) {
00027         case 0:
00028             wr_reg(ST7735_MADCTL, 0x0008);
00029             break;
00030         case 1:
00031             wr_reg(ST7735_MADCTL, 0x0068);
00032             break;
00033         case 2:
00034             wr_reg(ST7735_MADCTL, 0x00C8);
00035             break;
00036         case 3:
00037             wr_reg(ST7735_MADCTL, 0x00A8);
00038             break;
00039     }
00040 }
00041 void ST7735_TFT::wr_cmd(int cmd) {
00042     _rs = 0; // rs low, cs low for transmitting command
00043     _cs = 0;
00044     _spi.write(cmd);
00045     _cs = 1;
00046 }
00047 void ST7735_TFT::wr_dat(int dat) {
00048     _rs = 1; // rs high, cs low for transmitting data
00049     _cs = 0;                         
00050     _spi.write(dat);                                                           
00051     _cs = 1;
00052 }
00053 void ST7735_TFT::wr_dat_start(void) {
00054     _rs = 1; //  rs high, cs low for transmitting data
00055     _cs = 0;
00056 }
00057 void ST7735_TFT::wr_dat_stop (void) {
00058     _cs = 1;
00059 }
00060 void ST7735_TFT::wr_dat_only (unsigned short dat) {  
00061     _spi.write(dat);                                            
00062 }
00063 unsigned short ST7735_TFT::rd_dat (void) {
00064     unsigned short val = 0;
00065     _cs = 0;
00066     _spi.write(0);                                /* Dummy read 1                 */
00067     val   = _spi.write(0);                        /* Read D8..D15                 */
00068     val <<= 8;
00069     val  |= _spi.write(0);                        /* Read D0..D7                  */
00070     _cs = 1;
00071     return (val);
00072 }
00073 void ST7735_TFT::wr_reg (unsigned char reg, unsigned short val) {
00074 
00075     wr_cmd(reg);
00076     wr_dat(val);
00077 }
00078 unsigned short ST7735_TFT::rd_reg (unsigned char reg) {
00079 
00080     wr_cmd(reg);
00081     return(rd_dat());
00082 }
00083 void ST7735_TFT::read_area(unsigned int x, unsigned int y, unsigned int w, unsigned int h,unsigned char *buffer) {
00084     // BEWARE !
00085     // DOES NOT WORK CORRECTLY YET !!!
00086     int val;
00087     window(x,y,w,h);
00088     wr_cmd(ST7735_RAMRD);  // write to RAM
00089     _cs = 0;
00090     _rs = 1;
00091     _spi.write(0);                                /* Dummy read 1                 */
00092     
00093     val   = _spi.write(0);                        /* Read D8..D15                 */
00094     val <<= 8;
00095     val  |= _spi.write(0);                        /* Read D0..D7                  */
00096     _cs = 1;
00097 }
00098 int ST7735_TFT::getpixel(unsigned int x, unsigned int y) {
00099     // BEWARE !
00100     // DOES NOT WORK CORRECTLY YET !!!
00101     int val;
00102    // _spi.format(8,3);
00103     wr_cmd(ST7735_CASET);  // column addr set
00104     wr_dat(0x00);
00105     wr_dat(x+2);   // XSTART 
00106     wr_dat(0x00);
00107     wr_dat(x+2+2);   // XEND
00108 
00109     wr_cmd(ST7735_RASET);  // row addr set
00110     wr_dat(0x00);
00111     wr_dat(y+1);    // YSTART
00112     wr_dat(0x00);
00113     wr_dat(y+1+1);    // YEND
00114     
00115     _rs = 0; // rs low, cs low for transmitting command
00116     _cs = 0;
00117     _spi.write(0x2E);
00118     _rs = 1;
00119     _spi.write(0x00);                                /* Dummy read 1                 */
00120     
00121     val   = _spi.write(0x00);                        /* Read D8..D15                 */
00122     val <<= 8;
00123     val  |= _spi.write(0x00);                        /* Read D0..D7                  */
00124 
00125     _cs = 1;
00126     return val;
00127 }
00128 void ST7735_TFT::tft_reset() {
00129      // init SPI
00130     _spi.format(8,3);                 // 8 bit spi mode 3
00131     _spi.frequency(15000000);         // 16Mhz SPI clock ... 15Mhz is maximum for display, but it seems to work
00132     _cs = 0;
00133     _reset = 1;                       // reset
00134     wait_ms(10);
00135     _reset = 0;                       // reset
00136     wait_ms(10);
00137     _reset = 1;                       // reset
00138     wait_ms(10);
00139     
00140     /* Start Initial Sequence ----------------------------------------------------*/
00141     wr_cmd(ST7735_SWRESET);                         /* SW Reset                       */
00142     wait_ms(150);
00143     wr_cmd(ST7735_SLPOUT);                         /* Out of sleepmode               */
00144     wait_ms(500);
00145     
00146     wr_cmd(ST7735_FRMCTR1);                         /* Frame rate in normal mode            */
00147     wr_dat(0x01);                              
00148     wr_dat(0x2C);
00149     wr_dat(0x2D);
00150     
00151     wr_cmd(ST7735_FRMCTR2);                         /* Frame rate in idle mode            */
00152     wr_dat(0x01);                              
00153     wr_dat(0x2C);
00154     wr_dat(0x2D);
00155 
00156     wr_cmd(ST7735_FRMCTR3);                         /* Frame rate in partial mode            */
00157     wr_dat(0x01);                              
00158     wr_dat(0x2C);
00159     wr_dat(0x2D);
00160     wr_dat(0x01);   // inversion mode settings                              
00161     wr_dat(0x2C);
00162     wr_dat(0x2D);
00163     
00164     wr_cmd(ST7735_INVCTR);   // Inverted mode off
00165     wr_dat(0x07);   
00166 
00167     wr_cmd(ST7735_PWCTR1);   // POWER CONTROL 1   
00168     wr_dat(0xA2); 
00169     wr_dat(0x02);           // -4.6V
00170     wr_dat(0x84);           // AUTO mode 
00171     
00172     wr_cmd(ST7735_PWCTR2);   // POWER CONTROL 2   
00173     wr_dat(0xC5);            // VGH25 = 2.4C VGSEL =-10 VGH = 3*AVDD
00174     
00175     wr_cmd(ST7735_PWCTR3);  // POWER CONTROL 3   
00176     wr_dat(0x0A);           // Opamp current small
00177     wr_dat(0x00);           // Boost freq
00178 
00179     wr_cmd(ST7735_PWCTR4);   // POWER CONTROL 4   
00180     wr_dat(0x8A);            // BCLK/2, Opamp current small / medium low 
00181     wr_dat(0x2A);            // 
00182   
00183     wr_cmd(ST7735_PWCTR5);   // POWER CONTROL 5   
00184     wr_dat(0x8A);            // BCLK/2, Opamp current small / medium low 
00185     wr_dat(0xEE);            //
00186     
00187     wr_cmd(ST7735_VMCTR1);   // POWER CONTROL 6   
00188     wr_dat(0x0E);            // 
00189 
00190     wr_cmd(ST7735_INVOFF);   // INVOFF
00191     
00192     wr_cmd(ST7735_MADCTL);   // ORIENTATION   
00193     wr_dat(0xC8);   // 
00194     
00195     wr_cmd(ST7735_COLMOD);   // COLOR MODE   
00196     wr_dat(0x05);            //      
00197     
00198     wr_cmd(ST7735_CASET);   // COLUMN ADDR SET   
00199     wr_dat(0x00);   //
00200     wr_dat(0x00);   // xstart = 0
00201     wr_dat(0x00);   //
00202     wr_dat(0x7F);   // xend = 127
00203     
00204     wr_cmd(ST7735_RASET);   // ROW ADDR SET   
00205     wr_dat(0x00);   //
00206     wr_dat(0x00);   // ystart = 0
00207     wr_dat(0x00);   //
00208     wr_dat(0x9F);   // yend = 159            
00209     
00210     /* Gamma settings  -----------------------------------------------------------*/
00211 
00212   wr_cmd(0xE0); // GMCTRP1
00213   wr_dat(0x02);
00214   wr_dat(0x1c);
00215   wr_dat(0x07);
00216   wr_dat(0x12);
00217   wr_dat(0x37);
00218   wr_dat(0x32);
00219   wr_dat(0x29);
00220   wr_dat(0x2d);
00221   wr_dat(0x29);
00222   wr_dat(0x25);
00223   wr_dat(0x2B);
00224   wr_dat(0x39);
00225   wr_dat(0x00);
00226   wr_dat(0x01);
00227   wr_dat(0x03);
00228   wr_dat(0x10);
00229   wr_cmd(0xE1); // GMCTRN1
00230   wr_dat(0x03); 
00231   wr_dat(0x1d); 
00232   wr_dat(0x07); 
00233   wr_dat(0x06); 
00234   wr_dat(0x2E); 
00235   wr_dat(0x2C); 
00236   wr_dat(0x29); 
00237   wr_dat(0x2D); 
00238   wr_dat(0x2E); 
00239   wr_dat(0x2E); 
00240   wr_dat(0x37); 
00241   wr_dat(0x3F); 
00242   wr_dat(0x00); 
00243   wr_dat(0x00); 
00244   wr_dat(0x02); 
00245   wr_dat(0x10); 
00246   
00247   wr_cmd(ST7735_DISPON); // display ON
00248   wait_ms(100);
00249 
00250   wr_cmd(ST7735_NORON);  // normal display on
00251   wait_ms(10);
00252   
00253   switch (orientation) {
00254         case 0:
00255             wr_reg(0xC8, 0x0008);
00256             break;
00257         case 1:
00258             wr_reg(0xC8, 0x0068);
00259             break;
00260         case 2:
00261             wr_reg(0xC8, 0x00C8);
00262             break;
00263         case 3:
00264             wr_reg(0xC8, 0x00A8);
00265             break;
00266     }
00267     WindowMax ();
00268 }
00269 void ST7735_TFT::pixel(int x, int y, int color) {
00270   if ((x >= width()) || (y >= height())) return;
00271   window(x,y,x+1,y+1);  
00272    _rs = 1; 
00273    _cs = 0;
00274    _spi.write(color);
00275    _spi.write(color>>8);       
00276    _cs = 1;
00277 }
00278 void ST7735_TFT::window (unsigned int x, unsigned int y, unsigned int w, unsigned int h) {
00279   wr_cmd(ST7735_CASET);  // column addr set
00280   wr_dat(0x00);
00281   wr_dat(x);   // XSTART 
00282   wr_dat(0x00);
00283   wr_dat(x+w-1);   // XEND
00284   wr_cmd(ST7735_RASET);  // row addr set
00285   wr_dat(0x00);
00286   wr_dat(y);    // YSTART
00287   wr_dat(0x00);
00288   wr_dat(y+h-1);    // YEND
00289   wr_cmd(ST7735_RAMWR);  // write to RAM
00290 }
00291 void ST7735_TFT::WindowMax (void) {
00292     window (0, 0, width(),  height());
00293 }
00294 
00295 void ST7735_TFT::cls (void) {
00296     unsigned int i;
00297     WindowMax();
00298     wr_dat_start();    
00299     for (i = 0; i < ( (width()) * (height())); i++) {
00300         
00301         //_spi.write(_background>>8);
00302         //_spi.write(_background); 
00303         
00304         _spi.fastWrite(_background>>8);
00305         _spi.fastWrite(_background);
00306                    
00307     }
00308     _spi.clearRX();
00309     wr_dat_stop();   
00310 }
00311 void ST7735_TFT::circle(int x0, int y0, int r, int color) {
00312     int draw_x0, draw_y0;
00313     int draw_x1, draw_y1;
00314     int draw_x2, draw_y2;
00315     int draw_x3, draw_y3;
00316     int draw_x4, draw_y4;
00317     int draw_x5, draw_y5;
00318     int draw_x6, draw_y6;
00319     int draw_x7, draw_y7;
00320     int xx, yy;
00321     int di;
00322     WindowMax();
00323     if (r == 0) {       /* no radius */
00324         return;
00325     }
00326     draw_x0 = draw_x1 = x0;
00327     draw_y0 = draw_y1 = y0 + r;
00328     if (draw_y0 < height()) {
00329         pixel(draw_x0, draw_y0, color);     /* 90 degree */
00330     }
00331     draw_x2 = draw_x3 = x0;
00332     draw_y2 = draw_y3 = y0 - r;
00333     if (draw_y2 >= 0) {
00334         pixel(draw_x2, draw_y2, color);    /* 270 degree */
00335     }
00336     draw_x4 = draw_x6 = x0 + r;
00337     draw_y4 = draw_y6 = y0;
00338     if (draw_x4 < width()) {
00339         pixel(draw_x4, draw_y4, color);     /* 0 degree */
00340     }
00341     draw_x5 = draw_x7 = x0 - r;
00342     draw_y5 = draw_y7 = y0;
00343     if (draw_x5>=0) {
00344         pixel(draw_x5, draw_y5, color);     /* 180 degree */
00345     }
00346     if (r == 1) {
00347         return;
00348     }
00349     di = 3 - 2*r;
00350     xx = 0;
00351     yy = r;
00352     while (xx < yy) {
00353 
00354         if (di < 0) {
00355             di += 4*xx + 6;
00356         } else {
00357             di += 4*(xx - yy) + 10;
00358             yy--;
00359             draw_y0--;
00360             draw_y1--;
00361             draw_y2++;
00362             draw_y3++;
00363             draw_x4--;
00364             draw_x5++;
00365             draw_x6--;
00366             draw_x7++;
00367         }
00368         xx++;
00369         draw_x0++;
00370         draw_x1--;
00371         draw_x2++;
00372         draw_x3--;
00373         draw_y4++;
00374         draw_y5++;
00375         draw_y6--;
00376         draw_y7--;
00377 
00378         if ( (draw_x0 <= width()) && (draw_y0>=0) ) {
00379             pixel(draw_x0, draw_y0, color);
00380         }
00381         if ( (draw_x1 >= 0) && (draw_y1 >= 0) ) {
00382             pixel(draw_x1, draw_y1, color);
00383         }
00384         if ( (draw_x2 <= width()) && (draw_y2 <= height()) ) {
00385             pixel(draw_x2, draw_y2, color);
00386         }
00387         if ( (draw_x3 >=0 ) && (draw_y3 <= height()) ) {
00388             pixel(draw_x3, draw_y3, color);
00389         }
00390         if ( (draw_x4 <= width()) && (draw_y4 >= 0) ) {
00391             pixel(draw_x4, draw_y4, color);
00392         }
00393         if ( (draw_x5 >= 0) && (draw_y5 >= 0) ) {
00394             pixel(draw_x5, draw_y5, color);
00395         }
00396         if ( (draw_x6 <=width()) && (draw_y6 <= height()) ) {
00397             pixel(draw_x6, draw_y6, color);
00398         }
00399         if ( (draw_x7 >= 0) && (draw_y7 <= height()) ) {
00400             pixel(draw_x7, draw_y7, color);
00401         }
00402     }
00403     return;
00404 }
00405 void ST7735_TFT::fillcircle(int x, int y, int r, int color) {
00406     int i;
00407     for (i = 0; i <= r; i++)
00408         circle(x,y,i,color);
00409 }
00410 void ST7735_TFT::hline(int x0, int x1, int y, int color) {
00411     int w;
00412     w = x1 - x0 + 1;
00413     window(x0,y,w,1);
00414     wr_cmd(0x2C);
00415     wr_dat_start();
00416     for (int x=0; x<w; x++) {
00417         //_spi.write(color);
00418         //_spi.write(color >> 8);
00419         _spi.fastWrite(color>>8);
00420         _spi.fastWrite(color);
00421     }
00422     _spi.clearRX();
00423     wr_dat_stop();
00424     return;
00425 }
00426 void ST7735_TFT::vline(int x, int y0, int y1, int color) {
00427     int h;
00428     h = y1 - y0 + 1;
00429     window(x,y0,1,h);
00430     wr_cmd(0x2C);
00431     wr_dat_start();
00432     for (int y=0; y<h; y++) {
00433         //_spi.write(color);
00434         //_spi.write(color >> 8);
00435         _spi.fastWrite(color>>8);
00436         _spi.fastWrite(color);
00437     }
00438     _spi.clearRX();
00439     wr_dat_stop();
00440     return;
00441 }
00442 void ST7735_TFT::line(int x0, int y0, int x1, int y1, int color) {
00443     WindowMax();
00444     int   dx = 0, dy = 0;
00445     int   dx_sym = 0, dy_sym = 0;
00446     int   dx_x2 = 0, dy_x2 = 0;
00447     int   di = 0;
00448     dx = x1-x0;
00449     dy = y1-y0;
00450 
00451     if (dx == 0) {        /* vertical line */
00452         if (y1 > y0) vline(x0,y0,y1,color);
00453         else vline(x0,y1,y0,color);
00454         return;
00455     }
00456     if (dx > 0) {
00457         dx_sym = 1;
00458     } else {
00459         dx_sym = -1;
00460     }
00461     if (dy == 0) {        /* horizontal line */
00462         if (x1 > x0) hline(x0,x1,y0,color);
00463         else  hline(x1,x0,y0,color);
00464         return;
00465     }
00466     if (dy > 0) {
00467         dy_sym = 1;
00468     } else {
00469         dy_sym = -1;
00470     }
00471     dx = dx_sym*dx;
00472     dy = dy_sym*dy;
00473     dx_x2 = dx*2;
00474     dy_x2 = dy*2;
00475     if (dx >= dy) {
00476         di = dy_x2 - dx;
00477         while (x0 != x1) {
00478 
00479             pixel(x0, y0, color);
00480             x0 += dx_sym;
00481             if (di<0) {
00482                 di += dy_x2;
00483             } else {
00484                 di += dy_x2 - dx_x2;
00485                 y0 += dy_sym;
00486             }
00487         }
00488         pixel(x0, y0, color);
00489     } else {
00490         di = dx_x2 - dy;
00491         while (y0 != y1) {
00492             pixel(x0, y0, color);
00493             y0 += dy_sym;
00494             if (di < 0) {
00495                 di += dx_x2;
00496             } else {
00497                 di += dx_x2 - dy_x2;
00498                 x0 += dx_sym;
00499             }
00500         }
00501         pixel(x0, y0, color);
00502     }
00503     return;
00504 }
00505 void ST7735_TFT::rect(int x0, int y0, int x1, int y1, int color) {
00506     if (x1 > x0) hline(x0,x1,y0,color);
00507     else  hline(x1,x0,y0,color);
00508     if (y1 > y0) vline(x0,y0,y1,color);
00509     else vline(x0,y1,y0,color);
00510     if (x1 > x0) hline(x0,x1,y1,color);
00511     else  hline(x1,x0,y1,color);
00512     if (y1 > y0) vline(x1,y0,y1,color);
00513     else vline(x1,y1,y0,color);
00514     return;
00515 }
00516 void ST7735_TFT::fillrect(int x0, int y0, int x1, int y1, int color) {
00517     int h = y1 - y0 ;
00518     int w = x1 - x0 ;
00519     int pixel = h * w;
00520     window(x0,y0,w,h);
00521     wr_cmd(0x2C);
00522     wr_dat_start();
00523     for (int p=0; p<pixel; p++) {
00524         //_spi.write(color);
00525         //_spi.write(color >> 8);
00526         _spi.fastWrite(color>>8);
00527         _spi.fastWrite(color);
00528         
00529         
00530     }
00531     _spi.clearRX();
00532     wr_dat_stop();
00533     return;
00534 }
00535 void ST7735_TFT::locate(int x, int y) {
00536     char_x = x;
00537     char_y = y;
00538 }
00539 int ST7735_TFT::columns() {
00540     return width() / font[1];
00541 }
00542 int ST7735_TFT::rows() {
00543     return height() / font[2];
00544 }
00545 int ST7735_TFT::_putc(int value) {
00546     if (value == '\n') {    // new line
00547         char_x = 0;
00548         char_y = char_y + font[2];
00549         if (char_y >= height() - font[2]) {
00550             char_y = 0;
00551         }
00552     } else {
00553         character(char_x, char_y, value);
00554      }
00555     return value;
00556 }
00557 void ST7735_TFT::character(int x, int y, int c) {
00558     unsigned int hor,vert,offset,bpl,j,i,b;
00559     unsigned char* sign;
00560     unsigned char z,w;
00561     if ((c < 31) || (c > 127)) return;   // test char range
00562     // read font parameter from start of array
00563     offset = font[0];                    // bytes / char
00564     hor = font[1];                       // get hor size of font
00565     vert = font[2];                      // get vert size of font
00566     bpl = font[3];                       // bytes per line
00567     if (char_x + hor > width()) {
00568         char_x = 0;
00569         char_y = char_y + vert;
00570        if (char_y >= height() - font[2]) {
00571             char_y = 0;
00572         }
00573     }
00574     window(char_x, char_y,hor,vert); // char box
00575     wr_cmd(0x2C);
00576     wr_dat_start();
00577     sign = &font[((c -32) * offset) + 4]; // start of char bitmap
00578     w = sign[0];                          // width of actual char
00579     for (j=0; j<vert; j++) {  //  vert line
00580         for (i=0; i<hor; i++) {   //  horz line
00581             z =  sign[bpl * i + ((j & 0xF8) >> 3)+1];
00582             b = 1 << (j & 0x07);
00583             if (( z & b ) == 0x00) {                  
00584                 //_spi.write(_background>>8);
00585                 //_spi.write(_background); 
00586                 _spi.fastWrite(_background>>8);
00587                 _spi.fastWrite(_background);                              
00588                   
00589             } else {                     
00590                // _spi.write(_foreground>>8);
00591                // _spi.write(_foreground); 
00592                 _spi.fastWrite(_foreground>>8); 
00593                 _spi.fastWrite(_foreground);     
00594                                  
00595             }
00596         }
00597     }
00598     _spi.clearRX();
00599     wr_dat_stop();
00600     if ((w + 2) < hor) {                   // x offset to next char
00601         char_x += w + 2;
00602     } else char_x += hor;
00603 }
00604 void ST7735_TFT::set_font(unsigned char* f) {
00605     font = f;
00606 }
00607 void ST7735_TFT::Bitmap(unsigned int x, unsigned int y, unsigned int w, unsigned int h,unsigned char *bitmap) {
00608     unsigned int    i,j; //value;
00609     unsigned short *bitmap_ptr = (unsigned short *)bitmap;
00610     window(x, y, w, h);
00611     wr_cmd(0x2C);
00612     wr_dat_start();
00613     for (j = 0; j < h; j++) {        //Lines
00614         for (i = 0; i < w; i++) {     // copy pixel data to TFT
00615             //_spi.write(*bitmap_ptr);    // one line
00616             //_spi.write(*bitmap_ptr >> 8);
00617             _spi.fastWrite(*bitmap_ptr);
00618             _spi.fastWrite(*bitmap_ptr >> 8);  
00619             bitmap_ptr++;
00620         }
00621     }
00622     _spi.clearRX();
00623     wr_dat_stop();
00624 }
00625 int ST7735_TFT::BMP_16(unsigned int x, unsigned int y, const char *Name_BMP) {
00626 // BEWARE !
00627 // NOT TESTED
00628 #define OffsetPixelWidth    18
00629 #define OffsetPixelHeigh    22
00630 #define OffsetFileSize      34
00631 #define OffsetPixData       10
00632 #define OffsetBPP           28
00633     char filename[50];
00634     unsigned char BMP_Header[54];
00635     unsigned short BPP_t;
00636     unsigned int PixelWidth,PixelHeigh,start_data;
00637     unsigned int    i,off;
00638     int padd,j;
00639     unsigned short *line;
00640     // get the filename
00641     //LocalFileSystem local("local"); not working on FRDM-KL25Z
00642     sprintf(&filename[0],"/local/");
00643     i=7;
00644     while (*Name_BMP!='\0') {
00645         filename[i++]=*Name_BMP++;
00646     }
00647     FILE *Image = fopen((const char *)&filename[0], "r");  // open the bmp file
00648     if (!Image) {
00649         return(0);      // error file not found !
00650     }
00651     fread(&BMP_Header[0],1,54,Image);      // get the BMP Header
00652 
00653     if (BMP_Header[0] != 0x42 || BMP_Header[1] != 0x4D) {  // check magic byte
00654         fclose(Image);
00655         return(-1);     // error no BMP file
00656     }
00657     BPP_t = BMP_Header[OffsetBPP] + (BMP_Header[OffsetBPP + 1] << 8);
00658     if (BPP_t != 0x0010) {
00659         fclose(Image);
00660         return(-2);     // error no 16 bit BMP
00661     }
00662     PixelHeigh = BMP_Header[OffsetPixelHeigh] + (BMP_Header[OffsetPixelHeigh + 1] << 8) + (BMP_Header[OffsetPixelHeigh + 2] << 16) + (BMP_Header[OffsetPixelHeigh + 3] << 24);
00663     PixelWidth = BMP_Header[OffsetPixelWidth] + (BMP_Header[OffsetPixelWidth + 1] << 8) + (BMP_Header[OffsetPixelWidth + 2] << 16) + (BMP_Header[OffsetPixelWidth + 3] << 24);
00664     if (PixelHeigh > height() + y || PixelWidth > width() + x) {
00665         fclose(Image);
00666         return(-3);      // to big
00667     }
00668     start_data = BMP_Header[OffsetPixData] + (BMP_Header[OffsetPixData + 1] << 8) + (BMP_Header[OffsetPixData + 2] << 16) + (BMP_Header[OffsetPixData + 3] << 24);
00669 
00670     line = (unsigned short *) malloc (PixelWidth); // we need a buffer for a line
00671     if (line == NULL) {
00672         return(-4);         // error no memory
00673     }
00674     // the lines are padded to multiple of 4 bytes
00675     padd = -1;
00676     do {
00677         padd ++;
00678     } while ((PixelWidth * 2 + padd)%4 != 0);
00679     window(x, y,PixelWidth,PixelHeigh);
00680     wr_cmd(0x2C);
00681     wr_dat_start();
00682     for (j = PixelHeigh - 1; j >= 0; j--) {               //Lines bottom up
00683         off = j * (PixelWidth * 2 + padd) + start_data;   // start of line
00684         fseek(Image, off ,SEEK_SET);
00685         fread(line,1,PixelWidth * 2,Image);       // read a line - slow !
00686         for (i = 0; i < PixelWidth; i++) {        // copy pixel data to TFT
00687             //_spi.write(line[i]);                  // 2 x 8 bit pixel
00688             //_spi.write(line[i]>>8);
00689             _spi.fastWrite(line[i]);
00690             _spi.fastWrite(line[i]>>8);
00691         } 
00692     }
00693     _spi.clearRX();
00694     wr_dat_stop();
00695     free (line);
00696     fclose(Image);
00697     return(1);
00698 }