Library to control a Graphics TFT connected to 4-wire SPI - revised for the Raio RA8875 Display Controller.

Dependents:   FRDM_RA8875_mPaint RA8875_Demo RA8875_KeyPadDemo SignalGenerator ... more

Fork of SPI_TFT by Peter Drescher

See Components - RA8875 Based Display

Enhanced touch-screen support - where it previous supported both the Resistive Touch and Capacitive Touch based on the FT5206 Touch Controller, now it also has support for the GSL1680 Touch Controller.

Offline Help Manual (Windows chm)

/media/uploads/WiredHome/ra8875.zip.bin (download, rename to .zip and unzip)

Revision:
44:207594dece70
Parent:
43:3becae133285
Child:
46:1321832f11d8
Child:
48:065cc320473e
Child:
50:2c4f474a2453
--- a/RA8875.cpp	Sun Mar 09 23:45:23 2014 +0000
+++ b/RA8875.cpp	Mon Mar 10 11:40:56 2014 +0000
@@ -1,9 +1,11 @@
 /// RA8875 Display Controller Library.
 /// 
 /// This is being created for a specific display from buydisplay.com,
-/// which is 480 x xxx. It has other attributes (like display controller
+/// which is 480 x 272. It has other attributes (like display controller
 /// managed backlight brightness. So, there are expectations and some
-/// defined constants based on that specific display.
+/// defined constants based on that specific display. Some initial work
+/// was done to support other display resolutions (e.g. 800 x 480), but
+/// this has not been tested.
 ///
 #include "RA8875.h"
 
@@ -84,6 +86,25 @@
     return noerror;
 }
 
+
+RetCode_t RA8875::SetLayerMode(uint8_t mode)
+{
+    WriteCommand(0x52, mode);
+    return noerror;
+}
+
+
+RetCode_t RA8875::SetLayerTransparency(uint8_t layer1, uint8_t layer2)
+{
+    if (layer1 > 8)
+        layer1 = 8;
+    if (layer2 > 8)
+        layer2 = 8;
+    WriteCommand(0x53, ((layer2 & 0xF) << 4) | (layer1 & 0xF));
+    return noerror;
+}
+
+
 #ifdef PERF_METRICS
 void RA8875::ClearPerformance()
 {
@@ -91,6 +112,7 @@
         metrics[i] = 0;
 }
 
+
 void RA8875::RegisterPerformance(method_e method)
 {
     unsigned long elapsed = performance.read_us();
@@ -99,6 +121,7 @@
         metrics[method] = elapsed;
 }
 
+
 void RA8875::ReportPerformance(Serial & pc)
 {
     pc.printf("\r\nPerformance Metrics\r\n");
@@ -108,6 +131,7 @@
 }
 #endif
 
+
 RetCode_t RA8875::WriteCommandW(uint8_t command, uint16_t data)
 {
     #if 1
@@ -127,6 +151,7 @@
     return noerror;
 }
 
+
 RetCode_t RA8875::WriteCommand(unsigned char command, unsigned int data)
 {
     select(true);
@@ -140,6 +165,7 @@
     return noerror;
 }
 
+
 RetCode_t RA8875::WriteDataW(uint16_t data)
 {
     select(true);
@@ -150,6 +176,7 @@
     return noerror;
 }
 
+
 RetCode_t RA8875::WriteData(unsigned char data)
 {
     select(true);
@@ -159,12 +186,14 @@
     return noerror;
 }
 
+
 unsigned char RA8875::ReadCommand(unsigned char command)
 {
     WriteCommand(command);
     return ReadData();
 }
 
+
 unsigned char RA8875::ReadData(void)
 {
     unsigned char data;
@@ -176,6 +205,7 @@
     return data;
 }
 
+
 uint16_t RA8875::ReadDataW(void)
 {
     uint16_t data;
@@ -188,6 +218,7 @@
     return data;
 }
 
+
 unsigned char RA8875::ReadStatus(void)
 {
     unsigned char data;
@@ -199,6 +230,7 @@
     return data;
 }
 
+
 dim_t RA8875::fontwidth(void)
 {
     if (font == NULL)
@@ -207,6 +239,7 @@
         return font[1];
 }
 
+
 dim_t RA8875::fontheight(void)
 {
     if (font == NULL)
@@ -215,31 +248,37 @@
         return font[2];
 }
 
+
 RetCode_t RA8875::locate(textloc_t column, textloc_t row)
 {
     return SetTextCursor(column * fontwidth(), row * fontheight());
 }
 
+
 int RA8875::columns(void)
 {
     return width() / fontwidth();
 }
 
+
 int RA8875::rows(void)
 {
     return height() / fontheight();
 }
 
+
 dim_t RA8875::width(void)
 {
     return (ReadCommand(0x14) + 1) * 8;
 }
 
+
 dim_t RA8875::height(void)
 {
     return (ReadCommand(0x19) | (ReadCommand(0x1A) << 8)) + 1;
 }
 
+
 dim_t RA8875::color_bpp(void)
 {
     if ((ReadCommand(0x10) & 0x0C) == 0x04)
@@ -248,6 +287,7 @@
         return 8;
 }
 
+
 RetCode_t RA8875::SetTextCursor(loc_t x, loc_t y)
 {
     cursor_x = x; cursor_y = y;     // for non-internal fonts
@@ -256,6 +296,7 @@
     return noerror;
 }
 
+
 loc_t RA8875::GetTextCursor_Y(void)
 {
     if (font == NULL)
@@ -264,6 +305,7 @@
         return cursor_y;
 }
 
+
 loc_t RA8875::GetTextCursor_X(void)
 {
     if (font == NULL)
@@ -272,6 +314,7 @@
         return cursor_x;
 }
 
+
 RetCode_t RA8875::SetTextCursorControl(cursor_t cursor, bool blink)
 {
     unsigned char mwcr0 = ReadCommand(0x40) & 0x0F; // retain direction, auto-increase
@@ -309,6 +352,7 @@
     return noerror;
 }
 
+
 RetCode_t RA8875::SetTextFont(RA8875::font_t font)
 {
     if (/*font >= RA8875::ISO8859_1 && */ font <= RA8875::ISO8859_4) {
@@ -319,6 +363,7 @@
     }
 }
 
+
 RetCode_t RA8875::SetTextFontControl(fill_t fillit,
     RA8875::font_angle_t angle, 
     RA8875::HorizontalScale hScale, 
@@ -344,6 +389,7 @@
     }
 }
 
+
 RetCode_t RA8875::SetTextFontSize(RA8875::HorizontalScale hScale, RA8875::VerticalScale vScale)
 {
     unsigned char reg = ReadCommand(0x22);
@@ -361,6 +407,7 @@
     }
 }
 
+
 int RA8875::_putc(int c)
 {
     if (font == NULL) {
@@ -370,6 +417,7 @@
     }
 }
 
+
 int RA8875::_external_putc(int c)
 {
     if (c) {
@@ -395,6 +443,7 @@
     return c;
 }
 
+
 int RA8875::_internal_putc(int c)
 {
     if (c) {
@@ -427,6 +476,7 @@
     return c;
 }
 
+
 RetCode_t RA8875::_StartGraphicsStream(void)
 {
     WriteCommand(0x40,0x00);    // Graphics write mode
@@ -434,23 +484,27 @@
     return noerror;
 }
 
+
 RetCode_t RA8875::_EndGraphicsStream(void)
 {
     return noerror;
 }
 
+
 RetCode_t RA8875::putp(color_t pixel)
 {
     WriteDataW((pixel>>8) | (pixel<<8));
     return noerror;   
 }
 
+
 void RA8875::puts(loc_t x, loc_t y, const char * string)
 {
     SetTextCursor(x,y);
     puts(string);
 }
 
+
 void RA8875::puts(const char * string)
 {
     unsigned char mwcr0 = ReadCommand(0x40);
@@ -482,6 +536,7 @@
         _EndGraphicsStream();
 }
 
+
 RetCode_t RA8875::SetGraphicsCursor(loc_t x, loc_t y)
 {
     WriteCommandW(0x46, x);
@@ -489,6 +544,7 @@
     return noerror;
 }
 
+
 RetCode_t RA8875::SetGraphicsCursorRead(loc_t x, loc_t y)
 {
     //WriteCommand(0x40, 0);  // Graphics mode
@@ -498,6 +554,7 @@
     return noerror;
 }
 
+
 RetCode_t RA8875::window(loc_t x, loc_t y, dim_t width, dim_t height)
 {
     GraphicsDisplay::window(x,y, width,height);
@@ -509,6 +566,7 @@
     return noerror;
 }
 
+
 RetCode_t RA8875::cls(void)
 {
     PERFORMANCE_RESET;
@@ -518,6 +576,7 @@
     return noerror;
 }
 
+
 RetCode_t RA8875::clsw(RA8875::Region_t region)
 {
     PERFORMANCE_RESET;
@@ -528,6 +587,7 @@
     return noerror;
 }
 
+
 RetCode_t RA8875::pixel(loc_t x, loc_t y, color_t color)
 {
     #if 1
@@ -538,6 +598,7 @@
     #endif
 }
 
+
 RetCode_t RA8875::pixel(loc_t x, loc_t y)
 {
     RetCode_t ret;
@@ -553,6 +614,7 @@
     return ret;
 }
 
+
 RetCode_t RA8875::pixelStream(color_t * p, uint32_t count, loc_t x, loc_t y)
 {
     PERFORMANCE_RESET;
@@ -571,6 +633,7 @@
     return(noerror);
 }
 
+
 color_t RA8875::getPixel(loc_t x, loc_t y)
 {
     color_t pixel;
@@ -590,6 +653,7 @@
     return pixel;
 }
 
+
 RetCode_t RA8875::getPixelStream(color_t * p, uint32_t count, loc_t x, loc_t y)
 {
     color_t pixel;
@@ -612,12 +676,14 @@
     return noerror;
 }
 
+
 RetCode_t RA8875::line(loc_t x1, loc_t y1, loc_t x2, loc_t y2, color_t color)
 {
     foreground(color);
     return line(x1,y1,x2,y2);
 }
 
+
 RetCode_t RA8875::line(loc_t x1, loc_t y1, loc_t x2, loc_t y2)
 {
     PERFORMANCE_RESET;
@@ -634,12 +700,14 @@
     return noerror;
 }
 
+
 RetCode_t RA8875::fillrect(loc_t x1, loc_t y1, loc_t x2, loc_t y2, 
     color_t color, fill_t fillit)
 {
     return rect(x1,y1,x2,y2,color,fillit);
 }
 
+
 RetCode_t RA8875::rect(loc_t x1, loc_t y1, loc_t x2, loc_t y2, 
     color_t color, fill_t fillit)
 {
@@ -647,6 +715,7 @@
     return rect(x1,y1,x2,y2,fillit);
 }
 
+
 RetCode_t RA8875::rect(loc_t x1, loc_t y1, loc_t x2, loc_t y2, 
     fill_t fillit)
 {
@@ -674,6 +743,7 @@
     return noerror;
 }
 
+
 RetCode_t RA8875::fillroundrect(loc_t x1, loc_t y1, loc_t x2, loc_t y2, 
     dim_t radius1, dim_t radius2, color_t color, fill_t fillit)
 {
@@ -681,6 +751,7 @@
     return roundrect(x1,y1,x2,y2,radius1,radius2,fillit);
 }
 
+
 RetCode_t RA8875::roundrect(loc_t x1, loc_t y1, loc_t x2, loc_t y2, 
     dim_t radius1, dim_t radius2, color_t color, fill_t fillit)
 {
@@ -688,6 +759,7 @@
     return roundrect(x1,y1,x2,y2,radius1,radius2,fillit);
 }
 
+
 RetCode_t RA8875::roundrect(loc_t x1, loc_t y1, loc_t x2, loc_t y2, 
     dim_t radius1, dim_t radius2, fill_t fillit)
 {
@@ -725,6 +797,7 @@
     return ret;
 }
 
+
 RetCode_t RA8875::triangle(loc_t x1, loc_t y1, loc_t x2, loc_t y2, 
     loc_t x3, loc_t y3, color_t color, fill_t fillit)
 {
@@ -735,6 +808,7 @@
     return ret;
 }
 
+
 RetCode_t RA8875::filltriangle(loc_t x1, loc_t y1, loc_t x2, loc_t y2, 
     loc_t x3, loc_t y3, color_t color, fill_t fillit)
 {
@@ -745,6 +819,7 @@
     return ret;
 }
 
+
 RetCode_t RA8875::triangle(loc_t x1, loc_t y1 ,loc_t x2, loc_t y2, 
     loc_t x3, loc_t y3, fill_t fillit)
 {
@@ -779,6 +854,7 @@
     return circle(x,y,radius,fillit);
 }
 
+
 RetCode_t RA8875::fillcircle(loc_t x, loc_t y, dim_t radius, 
     color_t color, fill_t fillit)
 {
@@ -786,6 +862,7 @@
     return circle(x,y,radius,fillit);
 }
 
+
 RetCode_t RA8875::circle(loc_t x, loc_t y, dim_t radius, fill_t fillit)
 {
     RetCode_t ret = noerror;
@@ -811,17 +888,20 @@
     return ret;
 }
 
+
 RetCode_t RA8875::ellipse(loc_t x, loc_t y, dim_t radius1, dim_t radius2, color_t color, fill_t fillit)
 {
     foreground(color);
     return ellipse(x,y,radius1,radius2,fillit);
 }
 
+
 RetCode_t RA8875::fillellipse(loc_t x, loc_t y, dim_t radius1, dim_t radius2, color_t color, fill_t fillit)
 {
     foreground(color);
     return ellipse(x,y,radius1,radius2,fillit);
 }
+
         
 RetCode_t RA8875::ellipse(loc_t x, loc_t y, dim_t radius1, dim_t radius2, fill_t fillit)
 {
@@ -849,6 +929,7 @@
     return ret;
 }
 
+
 RetCode_t RA8875::frequency(unsigned long Hz)
 {
     spi.frequency(Hz);
@@ -860,12 +941,14 @@
     return noerror;
 }
 
+
 RetCode_t RA8875::Power(bool on)
 {
     WriteCommand(0x01, (on) ? 0x80 : 0x00);
     return noerror;
 }
 
+
 RetCode_t RA8875::Reset(void)
 {
     WriteCommand(0x01, 0x01);   // Apply Display Off, Reset
@@ -895,6 +978,7 @@
     return noerror;
 }
 
+
 RetCode_t RA8875::Backlight(float brightness)
 {
     unsigned char b;
@@ -908,6 +992,7 @@
     return Backlight_u8(b);
 }
 
+
 RetCode_t RA8875::set_font(const unsigned char * _font)
 {
     if (font && ! _font) {
@@ -918,6 +1003,7 @@
     return noerror;     // trusting them, but it might be good to put some checks in here...
 }
 
+
 RetCode_t RA8875::background(color_t color)
 {
     GraphicsDisplay::background(color);
@@ -927,6 +1013,7 @@
     return noerror;
 }
 
+
 RetCode_t RA8875::background(unsigned char r, unsigned char g, unsigned char b)
 {
     background(RGB(r,g,b));
@@ -936,6 +1023,7 @@
     return noerror;
 }
 
+
 RetCode_t RA8875::foreground(color_t color)
 {
     GraphicsDisplay::foreground(color);
@@ -945,6 +1033,7 @@
     return noerror;
 }
 
+
 RetCode_t RA8875::foreground(unsigned char r, unsigned char g, unsigned char b)
 {
     foreground(RGB(r,g,b));
@@ -954,6 +1043,7 @@
     return noerror;
 }
 
+
 color_t RA8875::GetForeColor(void)
 {
     color_t color;
@@ -964,6 +1054,7 @@
     return color;
 }
 
+
 color_t RA8875::DOSColor(int i)
     {
     const color_t colors[16] = 
@@ -979,6 +1070,7 @@
         return 0;
     }
 
+
 const char * RA8875::DOSColorNames(int i) 
     {
     const char * names[16] = 
@@ -1006,6 +1098,7 @@
     return retval;
 }
 
+
 unsigned char RA8875::spiread(void)
 {
     unsigned char retval;
@@ -1015,12 +1108,14 @@
     return retval;
 }
 
+
 RetCode_t RA8875::select(bool chipsel)
 {
     cs = (chipsel == true) ? 0 : 1;
     return noerror;
 }
 
+
 RetCode_t RA8875::init(int width, int height, int color_bpp)
 {
     Backlight_u8(0);
@@ -1087,6 +1182,7 @@
 //    Everything from here down is test code.
 bool SuppressSlowStuff = false;
 
+
 void TextCursorTest(RA8875 & display, Serial & pc)
 {
     const char * iCursor = "The I-Beam cursor should be visible for this text.\r\n";
@@ -1139,6 +1235,7 @@
     display.SetTextCursorControl(NOCURSOR, false);
 }
 
+
 void BacklightTest(RA8875 & display, Serial & pc, float ramptime)
 {
     char buf[60];
@@ -1165,6 +1262,7 @@
     }
 }
 
+
 void BacklightTest2(RA8875 & display, Serial & pc)
 {
     int delay = 20;
@@ -1185,6 +1283,7 @@
     display.Backlight_u8(0);
 }
 
+
 void ExternalFontTest(RA8875 & display, Serial & pc)
 {
     if (!SuppressSlowStuff)
@@ -1206,6 +1305,7 @@
     //display.window(0,0, display.width(), display.height());
 }
 
+
 void DOSColorTest(RA8875 & display, Serial & pc)
 {
     if (!SuppressSlowStuff)
@@ -1229,6 +1329,7 @@
     }
 }
 
+
 void WebColorTest(RA8875 & display, Serial & pc)
 {
     if (!SuppressSlowStuff)
@@ -1248,6 +1349,7 @@
     display.SetTextFontSize(1,1);
 }
 
+
 void PixelTest(RA8875 & display, Serial & pc)
 {
     int i, c, x, y;
@@ -1267,6 +1369,7 @@
     }
 }
 
+
 void LineTest(RA8875 & display, Serial & pc)
 {
     int i, x, y, x2, y2;
@@ -1287,6 +1390,7 @@
     }
 }
 
+
 void RectangleTest(RA8875 & display, Serial & pc)
 {
     int i, x1,y1, x2,y2;
@@ -1312,6 +1416,69 @@
     }
 }
 
+
+void LayerTest(RA8875 & display, Serial & pc)
+{
+    loc_t i, x1,y1, x2,y2, r1,r2;
+
+    if (!SuppressSlowStuff)
+        pc.printf("Layer Test\r\n");
+
+    display.SelectLayer(0);
+    display.background(Black);
+    display.foreground(Blue);
+    display.cls();
+    display.puts(0,0, "Layer 0");
+    for (i=0; i<16; i++) {
+        x1 = rand() % 240;
+        y1 = 50 + rand() % 200;
+        x2 = x1 + rand() % 100;
+        y2 = y1 + rand() % 100;
+        r1 = rand() % (x2 - x1)/2;
+        r2 = rand() % (y2 - y1)/2;
+        display.roundrect(x1,y1, x2,y2, r1,r2, display.DOSColor(i));
+        if (!SuppressSlowStuff)
+            wait_ms(20);
+    }
+    if (!SuppressSlowStuff)
+        wait_ms(1000);
+
+    display.SelectLayer(1);
+    display.background(Black);
+    display.foreground(Yellow);
+    display.cls();
+    display.puts(240,0, "Layer 1");
+    for (i=0; i<16; i++) {
+        x1 = 300 + rand() % 100;
+        y1 = 70 + rand() % 200;
+        r1 = rand() % min(y1 - 20, 100);
+        display.circle(x1,y1,r1, display.DOSColor(i));
+        if (!SuppressSlowStuff)
+            wait_ms(20);
+    }
+    display.SetLayerMode(1);        // Show it after the build-up
+    if (!SuppressSlowStuff)
+        wait_ms(2000);
+
+    display.SelectLayer(0);
+    display.SetLayerMode(0);        // Show Layer 0 again
+    if (!SuppressSlowStuff)
+        wait_ms(1000);
+    display.SetLayerMode(3);        // Transparent mode
+    if (!SuppressSlowStuff)
+        wait_ms(1000);
+    for (i=0; i<=8; i++) {
+        display.SetLayerTransparency(i, 8-i);
+        if (!SuppressSlowStuff)
+            wait_ms(200);
+    }
+    
+    // Restore before we exit
+    display.SetLayerTransparency(0, 0);
+    display.SetLayerMode(0);        // Restore to layer 0
+}
+
+
 void RoundRectTest(RA8875 & display, Serial & pc)
 {
     loc_t i, x1,y1, x2,y2, r1,r2;
@@ -1342,6 +1509,7 @@
     }
 }
 
+
 void TriangleTest(RA8875 & display, Serial & pc)
 {
     int i, x1, y1, x2, y2, x3, y3;
@@ -1403,6 +1571,7 @@
     }
 }
 
+
 void CircleTest(RA8875 & display, Serial & pc)
 {
     int i, x, y, r1;
@@ -1428,6 +1597,7 @@
     }
 }
 
+
 void EllipseTest(RA8875 & display, Serial & pc)
 {
     int i,x,y,r1,r2;
@@ -1453,6 +1623,7 @@
     }
 }
 
+
 void TestGraphicsBitmap(RA8875 & display, Serial & pc)
 {
     LocalFileSystem local("local");
@@ -1467,6 +1638,7 @@
     int r = display.RenderBitmapFile(0,0, "/local/TestPat.bmp");
 }
 
+
 void SpeedTest(RA8875 & display, Serial & pc)
 {
     Timer t;
@@ -1487,14 +1659,16 @@
     TriangleTest(display, pc);
     CircleTest(display, pc);
     EllipseTest(display, pc);
+    LayerTest(display, pc);
     //TestGraphicsBitmap(display, pc);
     pc.printf("SpeedTest completed in %d msec\r\n", t.read_ms());
-    #ifdef DEBUG
+    #ifdef PERF_METRICS
     display.ReportPerformance(pc);
     #endif
     SuppressSlowStuff = false;
 }
 
+
 void PrintScreen(RA8875 & display, Serial & pc)
 {
     LocalFileSystem local("local");
@@ -1503,11 +1677,12 @@
     display.PrintScreen( 0,0, 480,272, "/local/Capture.bmp");
 }
 
+
 void RunTestSet(RA8875 & lcd, Serial & pc)
 {
     int q = 0;
     int automode = 0;
-    const unsigned char modelist[] = "BDWtGLFROTPCEb";   // auto-test in this order.
+    const unsigned char modelist[] = "BDWtGLlFROTPCEb";   // auto-test in this order.
 
     while(1) {
         pc.printf("\r\n"
@@ -1520,6 +1695,7 @@
                   "C - Circles           E - Ellipses\r\n"
                   "A - Auto Test mode    S - Speed Test\r\n"
                   "p - print screen      r - reset  \r\n"
+                  "l - layer test             \r\n"
                   #ifdef DEBUG
                   "0 - clear performance 1 - report performance\r\n"
                   #endif
@@ -1565,6 +1741,9 @@
             case 'L':
                 LineTest(lcd, pc);
                 break;
+            case 'l':
+                LayerTest(lcd, pc);
+                break;
             case 'R':
                 RectangleTest(lcd, pc);
                 break;