Added methods and features

Fork of SPI_TFT_ILI9341 by Peter Drescher

Revision:
8:8593d3668153
Parent:
7:4c30bea883bc
Child:
9:6d30a225a5c7
--- a/SPI_TFT_ILI9341.cpp	Sun Jan 26 20:54:21 2014 +0000
+++ b/SPI_TFT_ILI9341.cpp	Wed Apr 02 19:20:09 2014 +0000
@@ -15,6 +15,7 @@
 // 18.10.13 Better Circle function from Michael Ammann
 // 22.10.13 Fixes for Kinetis Board - 8 bit spi
 // 26.01.14 Change interface for BMP_16 to also use SD-cards
+// 30.03.14 WH Added some methods for M24SR F103, Fixed typos & warnings, General define for SPI_16 selection
 
 #include "SPI_TFT_ILI9341.h"
 #include "mbed.h"
@@ -25,28 +26,37 @@
 //extern DigitalOut xx;     // debug !!
 
 SPI_TFT_ILI9341::SPI_TFT_ILI9341(PinName mosi, PinName miso, PinName sclk, PinName cs, PinName reset, PinName dc, const char *name)
-    : _spi(mosi, miso, sclk), _cs(cs), _reset(reset), _dc(dc), GraphicsDisplay(name)
+//WH    : _spi(mosi, miso, sclk), _cs(cs), _reset(reset), _dc(dc), GraphicsDisplay(name)
+    : GraphicsDisplay(name), _spi(mosi, miso, sclk), _cs(cs), _reset(reset), _dc(dc) 
 {
-    clk = sclk;
-    orientation = 0;
+//WH    clk = sclk;
+//WH    orientation = 0;
+    _origin = Origin_LeftTop;  
     char_x = 0;
     tft_reset();
 }
 
 int SPI_TFT_ILI9341::width()
 {
-    if (orientation == 0 || orientation == 2) return 240;
-    else return 320;
+//    if (orientation == 0 || orientation == 2) return 240;
+//    else return 320;
+
+    if (_origin == Origin_LeftTop || _origin == Origin_RightBot) return TFT_WIDTH;
+    else return TFT_HEIGHT;
 }
 
 
 int SPI_TFT_ILI9341::height()
 {
-    if (orientation == 0 || orientation == 2) return 320;
-    else return 240;
+//    if (orientation == 0 || orientation == 2) return 320;
+//    else return 240;
+
+    if (_origin == Origin_LeftTop || _origin == Origin_RightBot) return TFT_HEIGHT;
+    else return TFT_WIDTH;
 }
 
-
+//WH
+#if(0)
 void SPI_TFT_ILI9341::set_orientation(unsigned int o)
 {
     orientation = o;
@@ -66,8 +76,30 @@
             break;
     }
     _cs = 1; 
-    WindowMax();
+    window_max();
 } 
+#else
+void SPI_TFT_ILI9341::set_origin(Origin origin) {
+    _origin = origin;
+    wr_cmd(ILI9341_MAC);             // MEMORY_ACCESS_CONTROL
+    switch (_origin) {
+        case Origin_LeftTop:         /* Left Top of panel is origin */    
+            _spi.write(0x48);
+            break;
+        case Origin_RightTop:
+            _spi.write(0x28);
+            break;
+        case Origin_RightBot:
+            _spi.write(0x88);
+            break;
+        case Origin_LeftBot:
+            _spi.write(0xE8);
+            break;
+    }
+    _cs = 1; 
+    window_max();
+} 
+#endif
 
 
 // write command to tft register
@@ -88,7 +120,9 @@
 }
 
 
-
+//WH
+//Read not supported in M24SR
+#if(0)
 // the ILI9341 can read 
 
 char SPI_TFT_ILI9341::rd_byte(unsigned char cmd)
@@ -112,9 +146,9 @@
     _cs = 0;
     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);   
     _dc = 1;
     r = _spi.write(0xff);
     d = r;
@@ -136,14 +170,22 @@
     r = rd_byte(0x0A);
     return(r);
 }
+#endif
+
 
 
 // Init code based on MI0283QT datasheet
 
 void SPI_TFT_ILI9341::tft_reset()
 {
-    _spi.format(8,3);                  // 8 bit spi mode 3
-    _spi.frequency(10000000);          // 10 Mhz SPI clock
+//WH    _spi.format(8,0);                  // 8 bit spi Mode 0
+    _spi.format(8,0);                  // 8 bit spi mode 0    
+    
+//WH    _spi.frequency(10000000);          // 10 Mhz SPI doesnt work on current version of mbed F103 lib due to issue with HSI/HSE...
+//    _spi.frequency(4000000);          // 4 Mhz SPI clock ==> 2.2Mhz
+    _spi.frequency(8000000);          // 8 Mhz SPI clock ==> Mhz
+
+    
     _cs = 1;                           // cs high
     _dc = 1;                           // dc high 
     _reset = 0;                        // display reset
@@ -152,31 +194,37 @@
     _reset = 1;                       // end hardware reset
     wait_ms(5);
      
-    wr_cmd(0x01);                     // SW reset  
+//WH    wr_cmd(0x01);                     // SW reset  
+    wr_cmd(ILI9341_DISPLAY_RST);      // SW reset      
     wait_ms(5);
-    wr_cmd(0x28);                     // display off  
+//WH    wr_cmd(0x28);                     // display off  
+    wr_cmd(ILI9341_DISPLAY_OFF);      // display off      
 
     /* Start Initial Sequence ----------------------------------------------------*/
-     wr_cmd(0xCF);                     
+//     wr_cmd(0xCF);    
+     wr_cmd(ILI9341_POWERB);    /* Power control B register */
      _spi.write(0x00);
      _spi.write(0x83);
      _spi.write(0x30);
      _cs = 1;
      
-     wr_cmd(0xED);                     
+//     wr_cmd(0xED);     
+     wr_cmd(ILI9341_POWER_SEQ); /* Power on sequence register */
      _spi.write(0x64);
      _spi.write(0x03);
      _spi.write(0x12);
      _spi.write(0x81);
      _cs = 1;
      
-     wr_cmd(0xE8);                     
+//     wr_cmd(0xE8);                     
+     wr_cmd(ILI9341_DTCA);      /* Driver timing control A */                      
      _spi.write(0x85);
      _spi.write(0x01);
      _spi.write(0x79);
      _cs = 1;
      
-     wr_cmd(0xCB);                     
+//     wr_cmd(0xCB);                     
+     wr_cmd(ILI9341_POWERA);    /* Power control A register */                     
      _spi.write(0x39);
      _spi.write(0x2C);
      _spi.write(0x00);
@@ -184,54 +232,66 @@
      _spi.write(0x02);
      _cs = 1;
            
-     wr_cmd(0xF7);                     
+//     wr_cmd(0xF7);                     
+     wr_cmd(ILI9341_PRC);       /* Pump ratio control register */                   
      _spi.write(0x20);
      _cs = 1;
            
-     wr_cmd(0xEA);                     
+//     wr_cmd(0xEA);                     
+     wr_cmd(ILI9341_DTCB);      /* Driver timing control B */                          
      _spi.write(0x00);
      _spi.write(0x00);
      _cs = 1;
      
-     wr_cmd(0xC0);                     // POWER_CONTROL_1
+//     wr_cmd(0xC0);                     // POWER_CONTROL_1
+     wr_cmd(ILI9341_POWER1);    // POWER_CONTROL_1   
      _spi.write(0x26);
      _cs = 1;
  
-     wr_cmd(0xC1);                     // POWER_CONTROL_2
+//     wr_cmd(0xC1);                     // POWER_CONTROL_2
+     wr_cmd(ILI9341_POWER2);    // POWER_CONTROL_2
      _spi.write(0x11);
      _cs = 1;
      
-     wr_cmd(0xC5);                     // VCOM_CONTROL_1
+//     wr_cmd(0xC5);                     // VCOM_CONTROL_1
+     wr_cmd(ILI9341_VCOM1);     // VCOM_CONTROL_1     
      _spi.write(0x35);
      _spi.write(0x3E);
      _cs = 1;
      
-     wr_cmd(0xC7);                     // VCOM_CONTROL_2
+//     wr_cmd(0xC7);                     // VCOM_CONTROL_2
+     wr_cmd(ILI9341_VCOM2);     // VCOM_CONTROL_2     
      _spi.write(0xBE);
      _cs = 1; 
      
-     wr_cmd(0x36);                     // MEMORY_ACCESS_CONTROL
+//     wr_cmd(0x36);                     // MEMORY_ACCESS_CONTROL
+     wr_cmd(ILI9341_MAC);       // MEMORY_ACCESS_CONTROL     
      _spi.write(0x48);
      _cs = 1; 
      
-     wr_cmd(0x3A);                     // COLMOD_PIXEL_FORMAT_SET
+//     wr_cmd(0x3A);                     // COLMOD_PIXEL_FORMAT_SET
+     wr_cmd(ILI9341_PIXEL_FORMAT); /* Pixel Format register */
      _spi.write(0x55);                 // 16 bit pixel 
      _cs = 1;
      
-     wr_cmd(0xB1);                     // Frame Rate
+//     wr_cmd(0xB1);                     // Frame Rate
+     wr_cmd(ILI9341_FRC);          /* Frame Rate Control register */
      _spi.write(0x00);
      _spi.write(0x1B);               
      _cs = 1;
      
-     wr_cmd(0xF2);                     // Gamma Function Disable
-     _spi.write(0x08);
+//     wr_cmd(0xF2);                     // Gamma Function Disable
+     wr_cmd(ILI9341_3GAMMA_EN);    /* 3 Gamma enable register */     
+     _spi.write(0x08);             // Gamma Function Disable
      _cs = 1; 
      
-     wr_cmd(0x26);                     
+//     wr_cmd(0x26);                     
+     wr_cmd(ILI9341_GAMMA);        /* Gamma register */
      _spi.write(0x01);                 // gamma set for curve 01/2/04/08
      _cs = 1; 
      
-     wr_cmd(0xE0);                     // positive gamma correction
+//     wr_cmd(0xE0);                     // positive gamma correction
+     wr_cmd(ILI9341_PGAMMA);       /* Positive Gamma Correction register*/     
      _spi.write(0x1F); 
      _spi.write(0x1A); 
      _spi.write(0x18); 
@@ -249,7 +309,8 @@
      _spi.write(0x00);
      _cs = 1;
      
-     wr_cmd(0xE1);                     // negativ gamma correction
+//     wr_cmd(0xE1);                     // negativ gamma correction
+     wr_cmd(ILI9341_NGAMMA);       /* Negative Gamma Correction register*/
      _spi.write(0x00); 
      _spi.write(0x25); 
      _spi.write(0x27); 
@@ -267,31 +328,35 @@
      _spi.write(0x1F);
      _cs = 1;
      
-     WindowMax ();
-     
-     //wr_cmd(0x34);                     // tearing effect off
+     window_max();
+
+     //wr_cmd(ILI9341_TEAR_OFF);           // tearing effect off
      //_cs = 1;
      
-     //wr_cmd(0x35);                     // tearing effect on
+     //wr_cmd(ILI9341_TEAR_ON);            // tearing effect on
      //_cs = 1;
       
-     wr_cmd(0xB7);                       // entry mode
+//WH     wr_cmd(0xB7);                       // entry mode
+     wr_cmd(ILI9341_ENTRY_MODE);          // entry mode         
      _spi.write(0x07);
      _cs = 1;
      
-     wr_cmd(0xB6);                       // display function control
+//     wr_cmd(0xB6);                       // display function control
+     wr_cmd(ILI9341_DFC);                /* Display Function Control register*/     
      _spi.write(0x0A);
      _spi.write(0x82);
      _spi.write(0x27);
      _spi.write(0x00);
      _cs = 1;
      
-     wr_cmd(0x11);                     // sleep out
+//     wr_cmd(0x11);                     // sleep out
+     wr_cmd(ILI9341_SLEEP_OUT);          // sleep out     
      _cs = 1;
      
      wait_ms(100);
      
-     wr_cmd(0x29);                     // display on
+//     wr_cmd(0x29);                     // display on
+     wr_cmd(ILI9341_DISPLAY_ON); 
      _cs = 1;
      
      wait_ms(100);
@@ -301,37 +366,61 @@
 
 void SPI_TFT_ILI9341::pixel(int x, int y, int color)
 {
-    wr_cmd(0x2A);
+//    wr_cmd(0x2A);
+    wr_cmd(ILI9341_COLUMN_ADDR);
     _spi.write(x >> 8);
     _spi.write(x);
     _cs = 1;
-    wr_cmd(0x2B);
+    
+//    wr_cmd(0x2B);
+    wr_cmd(ILI9341_PAGE_ADDR);
     _spi.write(y >> 8);
     _spi.write(y);
     _cs = 1;
-    wr_cmd(0x2C);  // send pixel
+
+//    wr_cmd(0x2C);  // send pixel
+    wr_cmd(ILI9341_GRAM);  // send pixel     
+
+//WH
+#if(0)
     #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.format(16,0);                            // switch to 16 bit Mode 0
     _spi.write(color);                              // Write D0..D15
-    _spi.format(8,3);
+    _spi.format(8,0);
     #endif
+#endif
+
+    #if (SPI_16 == 1)
+    // 16 Bit SPI
+    _spi.format(16,0);                            // switch to 16 bit Mode 0
+    _spi.write(color);                            // Write D0..D15
+    _spi.format(8,0);                             // switch back to 8 bit Mode 0
+    #else 
+    // 8 Bit SPI
+    _spi.write(color >> 8);
+    _spi.write(color & 0xff);   
+    #endif
+
     _cs = 1;
 }
 
 
 void SPI_TFT_ILI9341::window (unsigned int x, unsigned int y, unsigned int w, unsigned int h)
 {
-    wr_cmd(0x2A);
+
+//    wr_cmd(0x2A);
+    wr_cmd(ILI9341_COLUMN_ADDR);
     _spi.write(x >> 8);
     _spi.write(x);
     _spi.write((x+w-1) >> 8);
-    _spi.write(x+w-1);
-    
+    _spi.write(x+w-1);   
     _cs = 1;
-    wr_cmd(0x2B);
+
+//    wr_cmd(0x2B);
+    wr_cmd(ILI9341_PAGE_ADDR);  
     _spi.write(y >> 8);
     _spi.write(y);
     _spi.write((y+h-1) >> 8);
@@ -340,17 +429,18 @@
 }
 
 
-void SPI_TFT_ILI9341::WindowMax (void)
+void SPI_TFT_ILI9341::window_max (void)
 {
-    window (0, 0, width(),  height());
+  window (0, 0, width(),  height());
 }
 
 
-
+//WH
+#if(0)
 void SPI_TFT_ILI9341::cls (void)
 {
     int pixel = ( width() * height());
-    WindowMax();
+    window_max();
     wr_cmd(0x2C);  // send pixel
     #if defined TARGET_KL25Z  // 8 Bit SPI
     unsigned int i;
@@ -360,15 +450,26 @@
         }
     
     #else 
-    _spi.format(16,3);                            // switch to 16 bit Mode 3
+    _spi.format(16,0);                            // switch to 16 bit Mode 0
     unsigned int i;
     for (i = 0; i < ( width() * height()); i++)
         _spi.write(_background);
-    _spi.format(8,3);    
+    _spi.format(8,0);    
     #endif                         
     _cs = 1; 
 }
+#else
 
+/** Fill the screen with _background color
+  *  @param none
+  *  @return none
+  */  
+void SPI_TFT_ILI9341::cls()
+{  
+  fillrect(0, 0, width()-1, height()-1, _background);
+}    
+    
+#endif
 
 void SPI_TFT_ILI9341::circle(int x0, int y0, int r, int color)
 {
@@ -404,7 +505,8 @@
     } while (x <= 0);
 }
 
-
+//WH
+#if(0)
 void SPI_TFT_ILI9341::hline(int x0, int x1, int y, int color)
 {
     int w;
@@ -418,18 +520,52 @@
         _spi.write(color & 0xff);
     } 
     #else 
-    _spi.format(16,3);                            // switch to 16 bit Mode 3
+    _spi.format(16,0);                            // switch to 16 bit Mode 0
     int j;
     for (j=0; j<w; j++) {
         _spi.write(color);
     }
-    _spi.format(8,3);
+    _spi.format(8,0);
     #endif
     _cs = 1;
-    WindowMax();
+    window_max();
     return;
 }
+#else
+void SPI_TFT_ILI9341::hline(int x0, int x1, int y, int color)
+{
+    int i, w;
+    int msb, lsb;
+    w = x1 - x0 + 1;
+    window(x0,y,w,1);
+//    wr_cmd(0x2C);  // send pixel
+    wr_cmd(ILI9341_GRAM);  // send pixel         
+    
+#if (SPI_16 == 1)
+    // 16 Bit SPI
+    _spi.format(16,0);   // switch to 16 bit Mode 0
+    for (i = 0; i < w; i++)
+      _spi.write(color);
+    _spi.format(8,0);    // switch back to 8 bit Mode 0 
+#else
+    // 8 Bit SPI
+    msb = color >> 8;
+    lsb = color & 0xff;
+    for (i = 0; i < w; i++){
+      _spi.write(msb);
+      _spi.write(lsb);
+    }
+#endif        
 
+    _cs = 1;
+    window_max();
+}
+#endif
+
+
+
+//WH
+#if(0)
 void SPI_TFT_ILI9341::vline(int x, int y0, int y1, int color)
 {
     int h;
@@ -442,22 +578,51 @@
         _spi.write(color & 0xff);
     } 
     #else 
-    _spi.format(16,3);                            // switch to 16 bit Mode 3
+    _spi.format(16,0);                            // switch to 16 bit Mode 0
     for (int y=0; y<h; y++) {
         _spi.write(color);
     }
-    _spi.format(8,3);
+    _spi.format(8,0);
     #endif
     _cs = 1;
-    WindowMax();
+    window_max();
     return;
 }
+#else
+void SPI_TFT_ILI9341::vline(int x, int y0, int y1, int color)
+{
+    int i, h;
+    int msb, lsb;
+    
+    h = y1 - y0 + 1;
+    window(x,y0,1,h);
+//    wr_cmd(0x2C);  // send pixel
+    wr_cmd(ILI9341_GRAM);  // send pixel         
 
-
+#if (SPI_16 == 1)
+    // 16 Bit SPI
+    _spi.format(16,0);   // switch to 16 bit Mode 0
+    for (i = 0; i < h; i++)
+      _spi.write(color);
+    _spi.format(8,0);    // switch back to 8 bit Mode 0 
+#else
+    // 8 Bit SPI
+    msb = color >> 8;
+    lsb = color & 0xff;
+    for (i = 0; i < h; i++){
+      _spi.write(msb);
+      _spi.write(lsb);
+    }
+#endif        
+  
+    _cs = 1;
+    window_max();
+}
+#endif
 
 void SPI_TFT_ILI9341::line(int x0, int y0, int x1, int y1, int color)
 {
-    //WindowMax();
+    //window_max();
     int   dx = 0, dy = 0;
     int   dx_sym = 0, dy_sym = 0;
     int   dx_x2 = 0, dy_x2 = 0;
@@ -523,7 +688,7 @@
         }
         pixel(x0, y0, color);
     }
-    return;
+//WH    return;
 }
 
 
@@ -542,14 +707,14 @@
     if (y1 > y0) vline(x1,y0,y1,color);
     else vline(x1,y1,y0,color);
 
-    return;
+//WH    return;
 }
 
 
-
+//WH
+#if(0)
 void SPI_TFT_ILI9341::fillrect(int x0, int y0, int x1, int y1, int color)
 {
-
     int h = y1 - y0 + 1;
     int w = x1 - x0 + 1;
     int pixel = h * w;
@@ -561,17 +726,51 @@
         _spi.write(color & 0xff);
     }
    #else
-    _spi.format(16,3);                            // switch to 16 bit Mode 3
+    _spi.format(16,0);                            // switch to 16 bit Mode 0
     for (int p=0; p<pixel; p++) {
         _spi.write(color);
     }
-    _spi.format(8,3);
+    _spi.format(8,0);
     #endif
     _cs = 1;
-    WindowMax();
+    window_max();
     return;
 }
 
+#else
+
+void SPI_TFT_ILI9341::fillrect(int x0, int y0, int x1, int y1, int color)
+{  
+    int h = y1 - y0 + 1;  //may want to add a sanity check on y1 > y0
+    int w = x1 - x0 + 1;  //may want to add a sanity check on x1 > x0
+    int pixels = h * w;
+    int i, msb, lsb;        
+ 
+    window(x0,y0,w,h);
+//    wr_cmd(0x2C);  // send pixel
+    wr_cmd(ILI9341_GRAM);  // send pixel         
+
+#if (SPI_16 == 1)
+    // 16 Bit SPI
+    _spi.format(16,0);   // switch to 16 bit Mode 0
+    for (i = 0; i < pixels; i++)
+      _spi.write(color);
+    _spi.format(8,0);    // switch back to 8 bit Mode 0 
+#else
+    // 8 Bit SPI
+    msb = color >> 8;
+    lsb = color & 0xff;
+    for (i = 0; i < pixels; i++){
+      _spi.write(msb);
+      _spi.write(lsb);
+    }
+#endif        
+
+    _cs = 1; 
+}
+#endif
+
+
 
 void SPI_TFT_ILI9341::locate(int x, int y)
 {
@@ -583,14 +782,14 @@
 
 int SPI_TFT_ILI9341::columns()
 {
-    return width() / font[1];
+    return width() / _font[1];
 }
 
 
 
 int SPI_TFT_ILI9341::rows()
 {
-    return height() / font[2];
+    return height() / _font[2];
 }
 
 
@@ -599,8 +798,8 @@
 {
     if (value == '\n') {    // new line
         char_x = 0;
-        char_y = char_y + font[2];
-        if (char_y >= height() - font[2]) {
+        char_y = char_y + _font[2];
+        if (char_y >= height() - _font[2]) {
             char_y = 0;
         }
     } else {
@@ -609,7 +808,8 @@
     return value;
 }
 
-
+//WH
+#if(0)
 void SPI_TFT_ILI9341::character(int x, int y, int c)
 {
     unsigned int hor,vert,offset,bpl,j,i,b;
@@ -619,24 +819,24 @@
     if ((c < 31) || (c > 127)) return;   // test char range
 
     // read font parameter from start of array
-    offset = font[0];                    // bytes / char
-    hor = font[1];                       // get hor size of font
-    vert = font[2];                      // get vert size of font
-    bpl = font[3];                       // bytes per line
+    offset = _font[0];                   // bytes / char
+    hor    = _font[1];                   // get hor size of font
+    vert   = _font[2];                   // get vert size of font
+    bpl    = _font[3];                   // bytes per line
 
     if (char_x + hor > width()) {
         char_x = 0;
         char_y = char_y + vert;
-        if (char_y >= height() - font[2]) {
+        if (char_y >= height() - _font[2]) {
             char_y = 0;
         }
     }
     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
+    _spi.format(16,0);   
+    #endif                         // switch to 16 bit Mode 0
+    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
@@ -661,18 +861,89 @@
     }
     _cs = 1;
     #ifndef TARGET_KL25Z  // 16 Bit SPI
-    _spi.format(8,3);
+    _spi.format(8,0);
     #endif
-    WindowMax();
+    window_max();
+    if ((w + 2) < hor) {                   // x offset to next char
+        char_x += w + 2;
+    } else char_x += hor;
+}
+#else
+void SPI_TFT_ILI9341::character(int x, int y, int c)
+{
+    unsigned int hor,vert,offset,bpl,j,i,b;
+    unsigned char* symbol;
+    unsigned char z,w;
+
+    if ((c < 31) || (c > 127)) return;   // test char range
+
+    // read font parameter from start of array
+    offset = _font[0];                   // bytes / char
+    hor    = _font[1];                   // get hor size of font
+    vert   = _font[2];                   // get vert size of font
+    bpl    = _font[3];                   // bytes per line
+
+    if (char_x + hor > width()) {
+        char_x = 0;
+        char_y = char_y + vert;
+        if (char_y >= height() - _font[2]) {
+            char_y = 0;
+        }
+    }
+    window(char_x, char_y, hor, vert); // char box
+//    wr_cmd(0x2C);  // send pixel
+    wr_cmd(ILI9341_GRAM);  // send pixel         
+    
+    #if (SPI_16 == 1)
+    // 16 Bit SPI 
+    _spi.format(16,0);   // switch to 16 bit Mode 0
+    #endif                         
+    symbol = &_font[((c - 32) * offset) + 4]; // start of char bitmap
+    w = symbol[0];                            // width of actual char
+    for (j=0; j<vert; j++) {  //  vert line
+      for (i=0; i<hor; i++) {   //  horz line
+        z =  symbol[bpl * i + ((j & 0xF8) >> 3)+1];
+        b = 1 << (j & 0x07);
+        if (( z & b ) == 0x00) {
+          #if (SPI_16 == 1)
+          // 16 Bit SPI 
+          _spi.write(_background);
+          #else
+          // 8 Bit SPI           
+          _spi.write(_background >> 8);
+          _spi.write(_background & 0xff);
+          #endif
+        }
+        else {
+          #if (SPI_16 == 1)
+          // 16 Bit SPI
+          _spi.write(_foreground);
+          #else
+          // 8 Bit SPI                     
+          _spi.write(_foreground >> 8);
+          _spi.write(_foreground & 0xff);
+          #endif
+        } // if
+      } // for i
+    } // for j
+
+    _cs = 1;
+    #if (SPI_16 == 1)  // 16 Bit SPI
+    _spi.format(8,0);  // switch back to 8 bit Mode 0
+    #endif
+    window_max();
+
     if ((w + 2) < hor) {                   // x offset to next char
         char_x += w + 2;
     } else char_x += hor;
 }
 
+#endif
+
 
 void SPI_TFT_ILI9341::set_font(unsigned char* f)
 {
-    font = f;
+  _font = f;
 }
 
 
@@ -695,10 +966,12 @@
     } while (2*(w + padd)%4 != 0);
     window(x, y, w, h);
     bitmap_ptr += ((h - 1)* (w + padd));
-    wr_cmd(0x2C);  // send pixel
+//    wr_cmd(0x2C);  // send pixel
+    wr_cmd(ILI9341_GRAM);  // send pixel     
+        
     #ifndef TARGET_KL25Z  // 16 Bit SPI 
-    _spi.format(16,3);
-    #endif                            // switch to 16 bit Mode 3
+    _spi.format(16,0);
+    #endif                            // switch to 16 bit Mode 0
     for (j = 0; j < h; j++) {         //Lines
         for (i = 0; i < w; i++) {     // one line
             #if defined TARGET_KL25Z  // 8 Bit SPI
@@ -716,9 +989,9 @@
     }
     _cs = 1;
     #ifndef TARGET_KL25Z  // 16 Bit SPI 
-    _spi.format(8,3);
+    _spi.format(8,0);
     #endif
-    WindowMax();
+    window_max();
 }
 
 
@@ -787,10 +1060,12 @@
     } while ((PixelWidth * 2 + padd)%4 != 0);
 
     window(x, y,PixelWidth ,PixelHeigh);
-    wr_cmd(0x2C);  // send pixel
+//    wr_cmd(0x2C);  // send pixel
+    wr_cmd(ILI9341_GRAM);  // send pixel         
+    
     #ifndef TARGET_KL25Z // only 8 Bit SPI 
-    _spi.format(16,3);  
-    #endif                          // switch to 16 bit Mode 3
+    _spi.format(16,0);  
+    #endif                          // switch to 16 bit Mode 0
     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);
@@ -805,9 +1080,64 @@
         } 
      }
     _cs = 1;
-    _spi.format(8,3);
+    _spi.format(8,0);
     free (line);
     fclose(Image);
-    WindowMax();
+    window_max();
     return(1);
 }
+
+
+/*******************************************************************************
+* Function Name  : WriteBMP_FAT
+* @brief Displays a bitmap picture loaded in Flash.
+* @param Xpos: specifies the X position.
+* @param Ypos: specifies the Y position.
+* @param BmpAddress: Bmp picture address in Flash.
+* @return None
+*******************************************************************************/
+void SPI_TFT_ILI9341::WriteBMP_FAT(uint16_t Xpos, uint16_t Ypos, const char* BmpName)
+{
+  uint32_t index = 0, size = 0, width=0, height=0;
+  uint16_t *pBmpWord=0;
+  uint16_t data;
+ 
+  /* Read bitmap width*/
+  width = BmpName[0]+1; 
+  /* Read bitmap height*/
+  height = BmpName[1]+1; 
+  /* Read bitmap size */
+  size   = width * height;  /* nb of 16 bits */
+    
+  window(Xpos, Ypos, width , height);    
+
+//  wr_cmd(0x2C);  // send pixel
+  wr_cmd(ILI9341_GRAM);  // send pixel       
+
+  /* Set WRX to send data */
+  _dc = 1;
+
+  pBmpWord = (uint16_t *) (&BmpName[5]);
+  /* Send them on the screen */
+  for(index = 0; index < size; index++)
+  {
+    _cs = 0;       
+
+    data = (*pBmpWord & 0x00FF);
+    _spi.write(data);
+
+    data = (*pBmpWord & 0xFF00)>>8;
+    _spi.write(data);
+           
+    _cs = 1;  
+      
+    pBmpWord++;
+  } 
+
+  /* Set LCD control line(/CS) */
+  _cs = 1;  
+        
+  window_max();
+}
+
+