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.

Fork of UniGraphic by GraphicsDisplay

Revision:
1:ff019d22b275
Parent:
0:75ec1b3cde17
Child:
2:713844a55c4e
--- a/Display/LCD.cpp	Thu Feb 12 22:22:47 2015 +0000
+++ b/Display/LCD.cpp	Fri Feb 13 15:25:10 2015 +0000
@@ -4,7 +4,8 @@
 //#define LCDPAGES        (LCDSIZE_Y>>3) // 8raws per page
 //#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 USEFRAMEBUFFER
+#define NOPCMD 0xE300
 //#define FRAMEBUFSIZE    (LCDSIZE_X*LCDPAGES)
 Protocols* proto;
 
@@ -16,46 +17,72 @@
   //  buffer = new unsigned char [LCDSIZE_X*LCDPAGES];
   //  PAR8 par8proto(port, CS, reset, DC, WR, RD);
     if(displayproto==PAR_8) proto = new PAR8(port, CS, reset, DC, WR, RD);
+    useNOP=false;
     buffer = (unsigned char*) malloc (LCDSIZE_X*LCDPAGES);
+    buffer16 = (unsigned short*)buffer;
     draw_mode = NORMAL;
     set_orientation(1);
   //  cls();
   //  locate(0,0);
 }
-LCD::LCD(proto_t displayproto,PinName mosi, PinName miso, PinName sclk, PinName CS, PinName reset, PinName DC, const int lcdsize_x, const int lcdsize_y, const int ic_x_segs, const int ic_y_coms, const char *name)
+LCD::LCD(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 int ic_x_segs, const int ic_y_coms, const char *name)
     : 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)
 {
  //   LCDPAGES = LCDSIZE_Y>>3;
  //   IC_PAGES = IC_Y_COMS>>3;
   //  buffer = new unsigned char [LCDSIZE_X*LCDPAGES];
   //  PAR8 par8proto(port, CS, reset, DC, WR, RD);
-    if(displayproto==SPI_8) proto = new SPI8(mosi, miso, sclk, CS, reset, DC);
+    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;
+    }
     buffer = (unsigned char*) malloc (LCDSIZE_X*LCDPAGES);
+    buffer16 = (unsigned short*)buffer;
     draw_mode = NORMAL;
   //  cls();
     set_orientation(1);
   //  locate(0,0);
+
 }
 LCD::~LCD()
 {
     free(buffer);
 }
 
-void LCD::wr_cmd(unsigned char cmd)
+void LCD::wr_cmd8(unsigned char cmd)
     {
-        proto->wr_cmd(cmd);
+        if(useNOP) proto->wr_cmd16(NOPCMD|cmd);
+        else proto->wr_cmd8(cmd);
     }
-void LCD::wr_data8(unsigned char data8)
+void LCD::wr_data8(unsigned char data)
     {
-        proto->wr_data8(data8);
+        proto->wr_data8(data);
+    }
+void LCD::wr_data8(unsigned char data, unsigned int count)
+    {
+        proto->wr_data8(data, count);
     }
-void LCD::wr_data8(unsigned char data8, unsigned int count)
+void LCD::wr_data8buf(unsigned char* data, unsigned int lenght)
     {
-        proto->wr_data8(data8, count);
+        proto->wr_data8buf(data, lenght);
+    }
+void LCD::wr_cmd16(unsigned short cmd)
+    {
+        proto->wr_cmd16(cmd);
     }
-void LCD::wr_data8buf(unsigned char* data8, unsigned int lenght)
+void LCD::wr_data16(unsigned short data, unsigned int count)
     {
-        proto->wr_data8buf(data8, lenght);
+        proto->wr_data16(data, count);
+    }
+void LCD::wr_data16buf(unsigned short* data, unsigned int lenght)
+    {
+        proto->wr_data16buf(data, lenght);
     }
 void LCD::hw_reset()
     {
@@ -113,34 +140,34 @@
     switch (mode)
     {
         case(NONE):
-            wr_cmd(0xA0);
-            wr_cmd(0xC8); // this is in real Y mirror command, but seems most displays have COMs wired inverted, so assume this is the default no-y-mirror
+         //   wr_cmd8(0xA0);
+            wr_cmd16(0xA0C8); // this is in real Y mirror command, but seems most displays have COMs wired inverted, so assume this is the default no-y-mirror
             break;
         case(X):
-            wr_cmd(0xA1);
-            wr_cmd(0xC8);
+        //    wr_cmd8(0xA1);
+            wr_cmd16(0xA1C8);
             break;
         case(Y):
-            wr_cmd(0xA0);
-            wr_cmd(0xC0);
+        //    wr_cmd8(0xA0);
+            wr_cmd16(0xA0C0);
             break;
         case(XY):
-            wr_cmd(0xA1);
-            wr_cmd(0xC0);
+        //    wr_cmd8(0xA1);
+            wr_cmd16(0xA1C0);
             break;
     }
 }
 void LCD::invert(unsigned char o)
 {
-    if(o == 0) wr_cmd(0xA6);
-    else wr_cmd(0xA7);
+    if(o == 0) wr_cmd8(0xA6);
+    else wr_cmd8(0xA7);
 }
 
 void LCD::set_contrast(int o)
 {
     contrast = o;
-    wr_cmd(0x81);      //  set volume
-    wr_cmd(o & 0x3F);
+ //   wr_cmd8(0x81);      //  set volume
+    wr_cmd16(0x8100|(o&0x3F));
 }
 void LCD::set_auto_up(bool up)
 {
@@ -184,8 +211,8 @@
 
 //    if(draw_mode == NORMAL)
 //    {
-        if(color == 0) buffer[x + ((y>>3) * LCDSIZE_X)] &= ~(1 << (y&7));  // erase pixel
-        else buffer[x + ((y>>3) * LCDSIZE_X)] |= (1 << (y&7));   // set pixel
+        if(color == 0) 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
 //    { // XOR mode
@@ -195,23 +222,27 @@
 void LCD::copy_to_lcd(void)
 {
     unsigned short i=0;
+    unsigned short setcolcmd = 0x0010 | ((col_offset&0xF)<<8) | (col_offset>>4);
     for(int page=0; page<LCDPAGES; page++)
     {
-        wr_cmd((unsigned char)col_offset&0xF);              // set column low nibble
-        wr_cmd(0x10|(col_offset>>4));      // set column hi  nibble
-        wr_cmd(0xB0|(page+page_offset));      // set page
-        wr_data8buf(buffer+i, LCDSIZE_X);   // send whole page pixels
-        i+=LCDSIZE_X;
+      //  wr_cmd8(col_offset&0xF);              // set column low nibble
+      //  wr_cmd8(0x10|(col_offset>>4));      // set column hi  nibble
+        wr_cmd16(setcolcmd);
+        wr_cmd8(0xB0|(page+page_offset));      // set page
+        wr_data16buf(buffer16+i, LCDSIZE_X>>1);   // send whole page pixels
+        i+=LCDSIZE_X>>1;
     }
 }
 void LCD::cls(void)
 {
     memset(buffer,0x00,LCDSIZE_X*LCDPAGES);  // clear display buffer
+    unsigned short setcolcmd = 0x0010 | ((col_offset&0xF)<<8) | (col_offset>>4);
     for(int page=0; page<LCDPAGES; page++)
     {
-        wr_cmd((unsigned char)col_offset&0xF);              // set column low nibble
-        wr_cmd(0x10|(col_offset>>4));      // set column hi  nibble
-        wr_cmd(0xB0|(page+page_offset));      // set page
-        wr_data8(0, LCDSIZE_X);   // send whole page pixels =0
+     //   wr_cmd8((unsigned char)col_offset&0xF);              // set column low nibble
+     //   wr_cmd8(0x10|(col_offset>>4));      // set column hi  nibble
+        wr_cmd16(setcolcmd);
+        wr_cmd8(0xB0|(page+page_offset));      // set page
+        wr_data16(0, LCDSIZE_X>>1);   // send whole page pixels =0
     }
 }
\ No newline at end of file