Basically i glued Peter Drescher and Simon Ford libs in a GraphicsDisplay class, then derived TFT or LCD class (which inherits Protocols class), then the most derived ones (Inits), which are per-display and are the only part needed to be adapted to diff hw.

Dependents:   testUniGraphic_150217 maze_TFT_MMA8451Q TFT_test_frdm-kl25z TFT_test_NUCLEO-F411RE ... more

Files at this revision

API Documentation at this revision

Comitter:
Geremia
Date:
Fri Feb 13 23:17:55 2015 +0000
Parent:
1:ff019d22b275
Child:
3:48f3282c2be8
Commit message:
Initial TFT implementation, needs to add read cmds

Changed in this revision

Display/LCD.cpp Show annotated file Show diff for this revision Revisions of this file
Display/LCD.h Show annotated file Show diff for this revision Revisions of this file
Display/TFT.cpp Show annotated file Show diff for this revision Revisions of this file
Display/TFT.h Show annotated file Show diff for this revision Revisions of this file
Graphics/GraphicsDisplay.cpp Show annotated file Show diff for this revision Revisions of this file
Graphics/GraphicsDisplay.h Show annotated file Show diff for this revision Revisions of this file
Inits/ILI9341.cpp Show annotated file Show diff for this revision Revisions of this file
Inits/ILI9341.h Show annotated file Show diff for this revision Revisions of this file
Inits/IST3020.cpp Show annotated file Show diff for this revision Revisions of this file
--- a/Display/LCD.cpp	Fri Feb 13 15:25:10 2015 +0000
+++ b/Display/LCD.cpp	Fri Feb 13 23:17:55 2015 +0000
@@ -5,9 +5,9 @@
 //#define IC_PAGES        (IC_Y_COMS>>3) // max pages in IC ddram, 8raws per page
 #define SWAP(a, b)  { a ^= b; b ^= a; a ^= b; }
 //#define USEFRAMEBUFFER
-#define NOPCMD 0xE300
+
 //#define FRAMEBUFSIZE    (LCDSIZE_X*LCDPAGES)
-Protocols* proto;
+
 
 LCD::LCD(proto_t displayproto, PortName port, PinName CS, PinName reset, PinName DC, PinName WR, PinName RD, const int lcdsize_x, const int lcdsize_y, const int ic_x_segs, const int ic_y_coms, const char *name)
     : /*PAR8(port, CS, reset, DC, WR, RD),*/ GraphicsDisplay(name), LCDSIZE_X(lcdsize_x), LCDSIZE_Y(lcdsize_y), LCDPAGES(lcdsize_y>>3), IC_X_SEGS(ic_x_segs), IC_Y_COMS(ic_y_coms), IC_PAGES(ic_y_coms>>3)
@@ -22,6 +22,9 @@
     buffer16 = (unsigned short*)buffer;
     draw_mode = NORMAL;
     set_orientation(1);
+    foreground(Black);
+    background(White);
+    set_auto_up(true);
   //  cls();
   //  locate(0,0);
 }
@@ -47,6 +50,9 @@
     draw_mode = NORMAL;
   //  cls();
     set_orientation(1);
+    foreground(Black);
+    background(White);
+    set_auto_up(true);
   //  locate(0,0);
 
 }
@@ -57,7 +63,7 @@
 
 void LCD::wr_cmd8(unsigned char cmd)
     {
-        if(useNOP) proto->wr_cmd16(NOPCMD|cmd);
+        if(useNOP) proto->wr_cmd16(0xE300|cmd); // E3 is NOP cmd for LCD
         else proto->wr_cmd8(cmd);
     }
 void LCD::wr_data8(unsigned char data)
@@ -169,15 +175,7 @@
  //   wr_cmd8(0x81);      //  set volume
     wr_cmd16(0x8100|(o&0x3F));
 }
-void LCD::set_auto_up(bool up)
-{
-    if(up) auto_up = true;
-    else auto_up = false;
-}
-bool LCD::get_auto_up(void)
-{
-    return (auto_up);
-}
+
 int LCD::get_contrast(void)
 {
     return(contrast);
@@ -203,6 +201,40 @@
         }
     }
 }
+void LCD::window_pushpixel(unsigned short color, unsigned int count) {
+    while(count)
+    {
+        pixel(cur_x, cur_y, color);
+        cur_x++;
+        if(cur_x > win_x2)
+        {
+            cur_x = win_x1;
+            cur_y++;
+            if(cur_y > win_y2)
+            {
+                cur_y = win_y1;
+            }
+        }
+        count--;
+    }
+}
+void LCD::window_pushpixelbuf(unsigned short* color, unsigned int lenght) {
+    while(lenght)
+    {
+        pixel(cur_x, cur_y, *color++);
+        cur_x++;
+        if(cur_x > win_x2)
+        {
+            cur_x = win_x1;
+            cur_y++;
+            if(cur_y > win_y2)
+            {
+                cur_y = win_y1;
+            }
+        }
+        lenght--;
+    }
+}
 void LCD::pixel(int x, int y, unsigned short color)
 {
     if(!(orientation&1)) SWAP(x,y);
@@ -211,7 +243,7 @@
 
 //    if(draw_mode == NORMAL)
 //    {
-        if(color == 0) buffer[(x + ((y>>3)*LCDSIZE_X))^1] &= ~(1 << (y&7));  // erase pixel
+        if(color == Black) buffer[(x + ((y>>3)*LCDSIZE_X))^1] &= ~(1 << (y&7));  // erase pixel
         else buffer[(x + ((y>>3)*LCDSIZE_X))^1] |= (1 << (y&7));   // set pixel
 //    }
 //    else
--- a/Display/LCD.h	Fri Feb 13 15:25:10 2015 +0000
+++ b/Display/LCD.h	Fri Feb 13 23:17:55 2015 +0000
@@ -8,10 +8,6 @@
 #include "SPI16.h"
 #include "Protocols.h"
 
-#define Black           1
-#define White           0
-
-
 
 /** Draw mode
   * NORMAl
@@ -76,6 +72,19 @@
     * @param color is the pixel color.
     */
     virtual void window_pushpixel(unsigned short color);
+    
+    /** Push some pixels of the same color into the window and increment position.
+    * You must first call window() then push pixels.
+    * @param color is the pixel color.
+    * @param count: how many
+    */
+    virtual void window_pushpixel(unsigned short color, unsigned int count);
+    
+    /** Push array of pixel colors into the window and increment position.
+    * You must first call window() then push pixels.
+    * @param color is the pixel color.
+    */
+    virtual void window_pushpixelbuf(unsigned short* color, unsigned int lenght);
  
     /** Framebuffer is used, it needs to be sent to LCD from time to time
     */
@@ -105,19 +114,7 @@
     */
     virtual void cls();
     
-    /** setup auto update of screen 
-      *
-      * @param up 1 = on , 0 = off
-      * if switched off the program has to call copy_to_lcd() 
-      * to update screen from framebuffer
-      */
-    void set_auto_up(bool up);
- 
-    /** get status of the auto update function
-      *
-      *  @returns if auto update is on
-      */
-    bool get_auto_up(void);
+    
     
     
     
@@ -219,7 +216,7 @@
     
 private:
 
-
+    Protocols* proto;
     unsigned char *buffer;
     unsigned short *buffer16;
     const int LCDSIZE_X;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Display/TFT.cpp	Fri Feb 13 23:17:55 2015 +0000
@@ -0,0 +1,154 @@
+#include "TFT.h"
+
+//#include "mbed_debug.h"
+
+#define SWAP(a, b)  { a ^= b; b ^= a; a ^= b; }
+
+TFT::TFT(proto_t displayproto, PortName port, PinName CS, PinName reset, PinName DC, PinName WR, PinName RD, const int lcdsize_x, const int lcdsize_y, const char *name)
+    : GraphicsDisplay(name), LCDSIZE_X(lcdsize_x), LCDSIZE_Y(lcdsize_y)
+{
+    if(displayproto==PAR_8) proto = new PAR8(port, CS, reset, DC, WR, RD);
+    useNOP=false;
+    set_orientation(0);
+    foreground(White);
+    background(Black);
+    set_auto_up(false); //we don't have framebuffer
+    mipistd=false;
+  //  cls();
+  //  locate(0,0);
+}
+TFT::TFT(proto_t displayproto, int Hz, PinName mosi, PinName miso, PinName sclk, PinName CS, PinName reset, PinName DC, const int lcdsize_x, const int lcdsize_y, const char *name)
+    : GraphicsDisplay(name), LCDSIZE_X(lcdsize_x), LCDSIZE_Y(lcdsize_y)
+{
+    if(displayproto==SPI_8)
+    {
+        proto = new SPI8(Hz, mosi, miso, sclk, CS, reset, DC);
+        useNOP=false;
+    }
+    else if(displayproto==SPI_16)
+    {
+        proto = new SPI16(Hz, mosi, miso, sclk, CS, reset, DC);
+        useNOP=true;
+    }
+  //  cls();
+    set_orientation(0);
+    foreground(White);
+    background(Black);
+    set_auto_up(false);
+    mipistd=false;
+  //  locate(0,0);
+}
+void TFT::wr_cmd8(unsigned char cmd)
+    {
+        if(useNOP) proto->wr_cmd16(cmd); // 0x0000|cmd, 00 is NOP cmd for TFT
+        else proto->wr_cmd8(cmd);
+    }
+void TFT::wr_data8(unsigned char data)
+    {
+        proto->wr_data8(data);
+    }
+void TFT::wr_data8(unsigned char data, unsigned int count)
+    {
+        proto->wr_data8(data, count);
+    }
+void TFT::wr_data8buf(unsigned char* data, unsigned int lenght)
+    {
+        proto->wr_data8buf(data, lenght);
+    }
+void TFT::wr_cmd16(unsigned short cmd)
+    {
+        proto->wr_cmd16(cmd);
+    }
+void TFT::wr_data16(unsigned short data)
+    {
+        proto->wr_data16(data);
+    }
+void TFT::wr_data16(unsigned short data, unsigned int count)
+    {
+        proto->wr_data16(data, count);
+    }
+void TFT::wr_data16buf(unsigned short* data, unsigned int lenght)
+    {
+        proto->wr_data16buf(data, lenght);
+    }
+void TFT::hw_reset()
+    {
+        proto->hw_reset();
+    }
+void TFT::BusEnable(bool enable)
+    {
+        proto->BusEnable(enable);
+    }
+// color TFT can rotate in hw (swap raw<->columns) for landscape views
+void TFT::set_orientation(int o)
+{
+    orientation = o;
+    wr_cmd8(0x36);
+    switch (orientation) {
+        case 0:// default, portrait view 0°
+            if(mipistd) wr_data8(0x0A); // this is in real a vertical flip enabled, seems most displays are vertical flipped
+            else wr_data8(0x48); //48 for 9341
+            set_width(LCDSIZE_X);
+            set_height(LCDSIZE_Y);
+            break;
+        case 1:// landscape view +90°
+            if(mipistd) wr_data8(0x28); 
+            else wr_data8(0x29);//28 for 9341
+            set_width(LCDSIZE_Y);
+            set_height(LCDSIZE_X);
+            break;
+        case 2:// portrait view +180°
+            if(mipistd) wr_data8(0x09); 
+            else wr_data8(0x99);//88 for 9341
+            set_width(LCDSIZE_X);
+            set_height(LCDSIZE_Y);
+            break;
+        case 3:// landscape view -90°
+            if(mipistd) wr_data8(0x2B); 
+            else wr_data8(0xF8);//E8 for 9341
+            set_width(LCDSIZE_Y);
+            set_height(LCDSIZE_X);
+            break;
+    }
+}
+// TFT have both column and raw autoincrement inside a window, with internal counters
+void TFT::window(int x, int y, int w, int h)
+{
+    //ili9486 does not like truncated 2A/2B cmds, at least in par mode
+    //setting only start column/page would speedup, but needs a windowmax() before, maybe implement later
+    wr_cmd8(0x2A);
+    wr_data16(x);   //start column
+    wr_data16(x+w-1);//end column
+
+    wr_cmd8(0x2B);
+    wr_data16(y);   //start page
+    wr_data16(y+h-1);//end page
+    
+    wr_cmd8(0x2C);  //write mem, just send pixels color next
+}
+//for TFT, just send data, position counters are in hw
+void TFT::window_pushpixel(unsigned short color)
+{
+    proto->wr_data16(color);
+}
+void TFT::window_pushpixel(unsigned short color, unsigned int count)
+{
+    proto->wr_data16(color, count);
+}
+void TFT::window_pushpixelbuf(unsigned short* color, unsigned int lenght)
+    {
+        proto->wr_data16buf(color, lenght);
+    }
+void TFT::pixel(int x, int y, unsigned short color)
+{
+    window(x,y,1,1);
+    wr_data16(color);   // 2C expects 16bit parameters
+    //proto->wr_data16(color);
+}
+void TFT::cls (void)
+{
+    WindowMax();
+  //  wr_data16(_background,pixels);
+    wr_data16(0,LCDSIZE_X*LCDSIZE_Y);
+    //proto->wr_data16(_background,pixels);
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Display/TFT.h	Fri Feb 13 23:17:55 2015 +0000
@@ -0,0 +1,203 @@
+#ifndef MBED_TFT_H
+#define MBED_TFT_H
+
+#include "GraphicsDisplay.h"
+#include "PAR8.h"
+#include "SPI8.h"
+#include "SPI16.h"
+#include "Protocols.h"
+
+
+
+
+
+
+/** A common base class for monochrome Display
+*/
+class TFT : public GraphicsDisplay
+{
+
+public:         
+          
+    /** Create a monochrome LCD Parallel interface
+    * @param name The name used by the parent class to access the interface
+    */
+    TFT(proto_t displayproto,PortName port, PinName CS, PinName reset, PinName DC, PinName WR, PinName RD, const int lcdsize_x, const int lcdsize_y, const char* name);
+    
+    /** Create a monochrome LCD SPI interface
+    * @param name The name used by the parent class to access the interface
+    */
+    TFT(proto_t displayproto, int Hz, PinName mosi, PinName miso, PinName sclk, PinName CS, PinName reset, PinName DC, const int lcdsize_x, const int lcdsize_y, const char* name);
+    
+    /////// functions that come for free, but can be overwritten///////////////////////////////////////////////////
+/////// ----------------------------------------------------///////////////////////////////////////////////////
+
+    /** Draw a pixel in the specified color.
+    * @param x is the horizontal offset to this pixel.
+    * @param y is the vertical offset to this pixel.
+    * @param color defines the color for the pixel.
+    */
+    virtual void pixel(int x, int y, unsigned short color);        
+    
+    /** Set the window, which controls where items are written to the screen.
+    * When something hits the window width, it wraps back to the left side
+    * and down a row. If the initial write is outside the window, it will
+    * be captured into the window when it crosses a boundary.
+    * @param x is the left edge in pixels.
+    * @param y is the top edge in pixels.
+    * @param w is the window width in pixels.
+    * @param h is the window height in pixels.
+    */
+    virtual void window(int x, int y, int w, int h);
+
+    /** Push a single pixel into the window and increment position.
+    * You must first call window() then push pixels.
+    * @param color is the pixel color.
+    */
+    virtual void window_pushpixel(unsigned short color);
+    
+    /** Push some pixels of the same color into the window and increment position.
+    * You must first call window() then push pixels.
+    * @param color is the pixel color.
+    * @param count: how many
+    */
+    virtual void window_pushpixel(unsigned short color, unsigned int count);
+    
+    /** Push array of pixel colors into the window and increment position.
+    * You must first call window() then push pixels.
+    * @param color is the pixel color.
+    */
+    virtual void window_pushpixelbuf(unsigned short* color, unsigned int lenght);
+ 
+    /** Framebuffer is not used for TFT
+    */
+    virtual void copy_to_lcd(){ };
+
+    /** invert the screen
+      *
+      * @param o = 0 normal, 1 invert
+      */
+    void invert(unsigned char o);
+
+    /** clear the entire screen
+    * The inherited one sets windomax then fill with background color
+    * We override it to speedup
+    */
+    virtual void cls();
+    
+    /** Set the orientation of the screen
+    *  x,y: 0,0 is always top left 
+    *
+    * @param o direction to use the screen (0-3)
+    * 0 = default 0° portrait view
+    * 1 = +90° landscape view
+    * 2 = +180° portrait view
+    * 3 = -90° landscape view
+    *
+    */  
+    virtual void set_orientation(int o);
+    
+    /** Set ChipSelect high or low
+    * @param enable 0/1   
+    */
+    virtual void BusEnable(bool enable);
+    
+    
+protected:
+
+
+////// functions needed by parent class ///////////////////////////////////////
+////// -------------------------------- ///////////////////////////////////////
+
+    /** Send 8bit command to display controller 
+    *
+    * @param cmd: byte to send  
+    * @note if protocol is SPI16, it will insert NOP cmd before, so if cmd is a 2byte cmd, the second cmd will be broken. Use wr_cmd16 for 2bytes cmds
+    */   
+    void wr_cmd8(unsigned char cmd);
+    
+    /** Send 8bit data to display controller 
+    *
+    * @param data: byte to send   
+    *
+    */   
+    void wr_data8(unsigned char data);
+    
+    /** Send same 8bit data to display controller multiple times
+    *
+    * @param data: byte to send
+    * @param count: how many
+    *
+    */   
+    void wr_data8(unsigned char data, unsigned int count);
+    
+    /** Send array of data bytes to display controller
+    *
+    * @param data: unsigned char data array
+    * @param lenght: lenght of array
+    *
+    */   
+    void wr_data8buf(unsigned char* data, unsigned int lenght);
+    
+    /** Send 16bit command to display controller 
+    *
+    * @param cmd: halfword to send  
+    *
+    */   
+    void wr_cmd16(unsigned short cmd);
+    
+    /** Send 16bit data to display controller 
+    *
+    * @param data: halfword to send   
+    *
+    */   
+    void wr_data16(unsigned short data);
+    
+    /** Send same 16bit data to display controller multiple times
+    *
+    * @param data: halfword to send
+    * @param count: how many
+    *
+    */   
+    void wr_data16(unsigned short data, unsigned int count);
+    
+    /** Send array of data shorts to display controller
+    *
+    * @param data: unsigned short data array
+    * @param lenght: lenght (in shorts)
+    *
+    */   
+    void wr_data16buf(unsigned short* data, unsigned int lenght);
+    
+    /** HW reset sequence (without display init commands)   
+    */
+    void hw_reset();
+
+    
+private:
+
+    Protocols* proto;
+    const int LCDSIZE_X;
+    const int LCDSIZE_Y;
+ //   const int LCDPAGES;
+ //   const int IC_X_SEGS;
+ //   const int IC_Y_COMS;
+ //   const int IC_PAGES;
+    
+ //   int page_offset;
+ //   int col_offset;
+    // pixel location
+    int cur_x;
+    int cur_y;
+    // window location
+    int win_x1;
+    int win_x2;
+    int win_y1;
+    int win_y2;
+    int orientation;
+    unsigned int tftID;
+    bool mipistd;
+    bool useNOP;
+};
+
+#endif
\ No newline at end of file
--- a/Graphics/GraphicsDisplay.cpp	Fri Feb 13 15:25:10 2015 +0000
+++ b/Graphics/GraphicsDisplay.cpp	Fri Feb 13 23:17:55 2015 +0000
@@ -7,8 +7,8 @@
 #define SWAP(a, b)  { a ^= b; b ^= a; a ^= b; }
 GraphicsDisplay::GraphicsDisplay(const char *name):TextDisplay(name) {
     set_font((unsigned char*)Terminal6x8);
-    foreground(0xFFFF);
-    background(0x0000);
+ //   foreground(0xFFFF);
+ //   background(0x0000);
     char_x = 0;
     char_y = 0;
     oriented_width=0;
@@ -76,19 +76,19 @@
 }
 void GraphicsDisplay::hline(int x0, int x1, int y, unsigned short color)
 {
-    int len;
-    len = x1 - x0 + 1;
+    int len = x1 - x0 + 1;
     window(x0,y,len,1);
-    for (int j=0; j<len; j++) window_pushpixel(color);
+ //   for (int j=0; j<len; j++) window_pushpixel(color);
+    window_pushpixel(color, len);
     if(auto_up) copy_to_lcd();
     return;
 }
 void GraphicsDisplay::vline(int x, int y0, int y1, unsigned short color)
 {
-    int len;
-    len = y1 - y0 + 1;
+    int len = y1 - y0 + 1;
     window(x,y0,1,len);
-    for (int y=0; y<len; y++) window_pushpixel(color);
+  //  for (int y=0; y<len; y++) window_pushpixel(color);
+    window_pushpixel(color, len);
     if(auto_up) copy_to_lcd();
     return;
 }
@@ -194,7 +194,8 @@
     int w = x1 - x0 + 1;
     unsigned int pixels = h * w;
     window(x0,y0,w,h);
-    for (unsigned int p=0; p<pixels; p++) window_pushpixel(color);
+ //   for (unsigned int p=0; p<pixels; p++) window_pushpixel(color);
+    window_pushpixel(color, pixels);
     if(auto_up) copy_to_lcd();
     return;
 }
@@ -327,7 +328,7 @@
     for (j = 0; j < h; j++) {         //Lines
         if((h + y) >= oriented_height) break; // no need to crop Y
         for (i = 0; i < w; i++) {     // one line
-                if((w + x) < oriented_width) window_pushpixel(*bitmap_ptr);
+                if((w + x) < oriented_width) window_pushpixel(*bitmap_ptr); //fixme, send chunk w-cropX lenght and incr bitmapptr if out of margin
                 bitmap_ptr++;
         }
         bitmap_ptr -= 2*w;
@@ -405,10 +406,13 @@
         off = j * (PixelWidth  * 2 + padd) + start_data;   // start of line
         fseek(Image, off ,SEEK_SET);
         fread(line,1,PixelWidth * 2,Image);       // read a line - slow 
-        for (i = 0; i < PixelWidth; i++) {        // copy pixel data to TFT
+  /*      for (i = 0; i < PixelWidth; i++)
+        {        // copy pixel data to TFT
      //       wr_16(line[i]);                  // one 16 bit pixel   
             window_pushpixel(line[i]);
-        } 
+            
+        } */
+        window_pushpixelbuf(line, PixelWidth);
      }
     free (line);
     fclose(Image);
@@ -425,6 +429,14 @@
         window_pushpixel(_background);
     }
 }
+void GraphicsDisplay::set_auto_up(bool up)
+{
+    if(up) auto_up = true;
+    else auto_up = false;
+}
+bool GraphicsDisplay::get_auto_up(void)
+{
+    return (auto_up);
+}
 
 
-
--- a/Graphics/GraphicsDisplay.h	Fri Feb 13 15:25:10 2015 +0000
+++ b/Graphics/GraphicsDisplay.h	Fri Feb 13 23:17:55 2015 +0000
@@ -17,6 +17,29 @@
 #include "TextDisplay.h"
 #include "Terminal6x8.h"
 
+#define RGB(r,g,b)  (((r&0xF8)<<8)|((g&0xFC)<<3)|((b&0xF8)>>3)) //5 red | 6 green | 5 blue
+#define BGR2RGB(color) (((color&0x1F)<<11) | (color&0x7E0) | ((color&0xF800)>>11))
+
+/* some RGB color definitions                                                 */
+#define Black           0x0000      /*   0,   0,   0 */
+#define Navy            0x000F      /*   0,   0, 128 */
+#define DarkGreen       0x03E0      /*   0, 128,   0 */
+#define DarkCyan        0x03EF      /*   0, 128, 128 */
+#define Maroon          0x7800      /* 128,   0,   0 */
+#define Purple          0x780F      /* 128,   0, 128 */
+#define Olive           0x7BE0      /* 128, 128,   0 */
+#define LightGrey       0xC618      /* 192, 192, 192 */
+#define DarkGrey        0x7BEF      /* 128, 128, 128 */
+#define Blue            0x001F      /*   0,   0, 255 */
+#define Green           0x07E0      /*   0, 255,   0 */
+#define Cyan            0x07FF      /*   0, 255, 255 */
+#define Red             0xF800      /* 255,   0,   0 */
+#define Magenta         0xF81F      /* 255,   0, 255 */
+#define Yellow          0xFFE0      /* 255, 255,   0 */
+#define White           0xFFFF      /* 255, 255, 255 */
+#define Orange          0xFD20      /* 255, 165,   0 */
+#define GreenYellow     0xAFE5      /* 173, 255,  47 */
+
 /** Bitmap
  */
 struct Bitmap_s{
@@ -69,6 +92,19 @@
     * @note this method must be overridden in a derived class.
     */
     virtual void window_pushpixel(unsigned short color) = 0;
+    
+    /** Push some pixels of the same color into the window and increment position.
+    * You must first call window() then push pixels.
+    * @param color is the pixel color.
+    * @param count: how many
+    */
+    virtual void window_pushpixel(unsigned short color, unsigned int count) = 0;
+    
+    /** Push array of pixel colors into the window and increment position.
+    * You must first call window() then push pixels.
+    * @param color is the pixel color.
+    */
+    virtual void window_pushpixelbuf(unsigned short* color, unsigned int lenght) = 0;
   
     /** If framebuffer is used, it needs to be sent to LCD from time to time
     @note this method must be overridden in a derived class.
@@ -277,12 +313,19 @@
     */
     void set_height(int height);
     
-    
-protected:
-
-    
-    
-    bool auto_up;  // autoupdate flag for LCD
+    /** setup auto update of screen 
+      *
+      * @param up 1 = on , 0 = off
+      * if switched off the program has to call copy_to_lcd() 
+      * to update screen from framebuffer
+      */
+    void set_auto_up(bool up);
+ 
+    /** get status of the auto update function
+      *
+      *  @returns if auto update is on
+      */
+    bool get_auto_up(void); 
     
     
     
@@ -303,8 +346,7 @@
     int fontbpl;   // bytes per line (char)
     unsigned char firstch;  // first ascii code present in font array (usually 32)
     unsigned char lastch;   // last ascii code present in font array (usually 127)
-    
-    
+    bool auto_up;  // autoupdate flag for LCD   
     
 
 };
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Inits/ILI9341.cpp	Fri Feb 13 23:17:55 2015 +0000
@@ -0,0 +1,152 @@
+#include "Protocols.h"
+#include "ILI9341.h"
+
+//////////////////////////////////////////////////////////////////////////////////
+// display settings ///////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+
+#define LCDSIZE_X       240 // display X pixels, TFTs are usually portrait view
+#define LCDSIZE_Y       320  // display Y pixels
+
+
+
+ILI9341::ILI9341(proto_t displayproto, PortName port, PinName CS, PinName reset, PinName DC, PinName WR, PinName RD, const char *name)
+    : TFT(displayproto, port, CS, reset, DC, WR, RD, LCDSIZE_X, LCDSIZE_Y, name)
+{
+    hw_reset();
+    BusEnable(true);
+    init();
+    cls();
+    set_orientation(0);
+    locate(0,0); 
+}
+ILI9341::ILI9341(proto_t displayproto, int Hz, PinName mosi, PinName miso, PinName sclk, PinName CS, PinName reset, PinName DC, const char *name)
+    : TFT(displayproto, Hz, mosi, miso, sclk, CS, reset, DC, LCDSIZE_X, LCDSIZE_Y, name)
+{
+    hw_reset(); //TFT class forwards to Protocol class
+    BusEnable(true); //TFT class forwards to Protocol class
+    init(); // per display custom init cmd sequence, implemented here
+    cls();
+    set_orientation(1); //TFT class does for MIPI standard and some ILIxxx
+    locate(0,0); 
+}
+// reset and init the lcd controller
+void ILI9341::init()
+{
+    /* Start Initial Sequence ----------------------------------------------------*/
+    
+    wr_cmd8(0xCB);  // POWER_ON_SEQ_CONTROL             
+     wr_data8(0x39);
+     wr_data8(0x2C);
+     wr_data8(0x00);
+     wr_data8(0x34);
+     wr_data8(0x02);
+     
+    wr_cmd8(0xCF);  // POWER_CONTROL_B              
+     wr_data8(0x00);
+     wr_data8(0xC1);  // Applic Notes 81, was 83, C1 enables PCEQ: PC and EQ operation for power saving
+     wr_data8(0x30);
+     
+     wr_cmd8(0xE8);  // DRIVER_TIMING_CONTROL_A               
+     wr_data8(0x85);
+     wr_data8(0x00);  // AN 10, was 01
+     wr_data8(0x78);  // AN 7A, was 79
+     
+     wr_cmd8(0xEA);  // DRIVER_TIMING_CONTROL_B                    
+     wr_data8(0x00);
+     wr_data8(0x00);
+     
+     wr_cmd8(0xED);                     
+     wr_data8(0x64);
+     wr_data8(0x03);
+     wr_data8(0x12);
+     wr_data8(0x81);
+     
+     wr_cmd8(0xF7);  // PUMP_RATIO_CONTROL                   
+     wr_data8(0x20);
+     
+     wr_cmd8(0xC0);                     // POWER_CONTROL_1
+     wr_data8(0x23);  // AN 21, was 26
+     
+     wr_cmd8(0xC1);                     // POWER_CONTROL_2
+     wr_data8(0x10);  // AN 11, was 11
+     
+     wr_cmd8(0xC5);                     // VCOM_CONTROL_1
+     wr_data8(0x3E);  // AN 3F, was 35
+     wr_data8(0x28);  // AN 3C, was 3E
+     
+     wr_cmd8(0xC7);                     // VCOM_CONTROL_2
+     wr_data8(0x86);  // AN A7, was BE
+     
+     wr_cmd8(0x36);                     // MEMORY_ACCESS_CONTROL
+     wr_data8(0x48);
+     
+     wr_cmd8(0x3A);                     // COLMOD_PIXEL_FORMAT_SET, not present in AN
+     wr_data8(0x55);                 // 16 bit pixel 
+     
+     wr_cmd8(0xB1);                     // Frame Rate
+     wr_data8(0x00);
+     wr_data8(0x18);  // AN 1B, was 1B  1B=70hz             
+     
+     wr_cmd8(0xB6);                       // display function control, INTERESTING
+     wr_data8(0x08);  // AN 0A, was 0A
+     wr_data8(0x82);  // AN A2
+     wr_data8(0x27);  // AN not present
+  //   wr_data8(0x00);  // was present
+     
+     wr_cmd8(0xF2);                     // Gamma Function Disable
+     wr_data8(0x00);  // AN 00, was 08
+     
+     wr_cmd8(0x26);                     
+     wr_data8(0x01);                 // gamma set for curve 01/2/04/08
+     
+     wr_cmd8(0xE0);                     // positive gamma correction
+     wr_data8(0x0F); 
+     wr_data8(0x31); 
+     wr_data8(0x2B); 
+     wr_data8(0x0C); 
+     wr_data8(0x0E); 
+     wr_data8(0x08); 
+     wr_data8(0x4E); 
+     wr_data8(0xF1); 
+     wr_data8(0x37); 
+     wr_data8(0x07); 
+     wr_data8(0x10); 
+     wr_data8(0x03); 
+     wr_data8(0x0E);
+     wr_data8(0x09); 
+     wr_data8(0x00);
+     
+     wr_cmd8(0xE1);                     // negativ gamma correction
+     wr_data8(0x00); 
+     wr_data8(0x0E); 
+     wr_data8(0x14); 
+     wr_data8(0x03); 
+     wr_data8(0x11); 
+     wr_data8(0x07); 
+     wr_data8(0x31); 
+     wr_data8(0xC1); 
+     wr_data8(0x48); 
+     wr_data8(0x08); 
+     wr_data8(0x0F); 
+     wr_data8(0x0C); 
+     wr_data8(0x31);
+     wr_data8(0x36); 
+     wr_data8(0x0F);
+     
+     //wr_cmd8(0x34);                     // tearing effect off
+     
+     //wr_cmd8(0x35);                     // tearing effect on
+      
+  //   wr_cmd8(0xB7);                       // ENTRY_MODE_SET
+  //   wr_data8(0x07);
+         
+     wr_cmd8(0x11);                     // sleep out
+     
+     wait_ms(150);
+     
+     wr_cmd8(0x29);                     // display on
+     
+     wait_ms(150);
+
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Inits/ILI9341.h	Fri Feb 13 23:17:55 2015 +0000
@@ -0,0 +1,54 @@
+#ifndef MBED_ILI9341_H
+#define MBED_ILI9341_H
+
+
+
+#include "mbed.h"
+#include "TFT.h"
+
+/** Class for ILI9341 tft display controller
+* to be copypasted and adapted for other controllers
+*/
+class ILI9341 : public TFT
+{
+ 
+ public:
+
+    /** Create a PAR display interface
+    * @param displayproto only supports PAR_8
+    * @param port GPIO port name to use
+    * @param CS pin connected to CS of display
+    * @param reset pin connected to RESET of display
+    * @param DC pin connected to data/command of display
+    * @param WR pin connected to SDI of display
+    * @param RD pin connected to RS of display
+    * @param name The name used by the parent class to access the interface
+    */ 
+    ILI9341(proto_t displayproto, PortName port, PinName CS, PinName reset, PinName DC, PinName WR, PinName RD, const char* name);
+  
+    /** Create an SPI display interface
+    * @param displayproto only supports SPI_8
+    * @param Hz SPI speed in Hz
+    * @param mosi SPI pin
+    * @param miso SPI pin
+    * @param sclk SPI pin
+    * @param CS pin connected to CS of display
+    * @param reset pin connected to RESET of display
+    * @param DC pin connected to data/command of display
+    * @param name The name used by the parent class to access the interface
+    */ 
+    ILI9341(proto_t displayproto, int Hz, PinName mosi, PinName miso, PinName sclk, PinName CS, PinName reset, PinName DC, const char* name);
+  
+
+  
+protected:
+    
+    
+    /** Init command sequence  
+    */
+    void init();
+
+
+
+};
+#endif
\ No newline at end of file
--- a/Inits/IST3020.cpp	Fri Feb 13 15:25:10 2015 +0000
+++ b/Inits/IST3020.cpp	Fri Feb 13 23:17:55 2015 +0000
@@ -16,13 +16,20 @@
 {
     hw_reset();
     BusEnable(true);
-    init();  
+    init();
+    cls();
+    set_orientation(1);
+    locate(0,0);
 }
 IST3020::IST3020(proto_t displayproto, int Hz, PinName mosi, PinName miso, PinName sclk, PinName CS, PinName reset, PinName DC, const char *name)
     : LCD(displayproto, Hz, mosi, miso, sclk, CS, reset, DC, LCDSIZE_X, LCDSIZE_Y, IC_X_SEGS, IC_Y_COMS, name)
 {
     hw_reset();
-    init();  
+    BusEnable(true);
+    init();
+    cls();
+    set_orientation(1);
+    locate(0,0);
 }
 // reset and init the lcd controller
 void IST3020::init()