Lib for the new LCD Display with ILI9341 controller supporting two displays

Dependents:   CANary_9341_test CANary_9341 CANary

Fork of SPI_TFT_ILI9341 by Peter Drescher

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers SPI_TFTx2_ILI9341.cpp Source File

SPI_TFTx2_ILI9341.cpp

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