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)

Files at this revision

API Documentation at this revision

Comitter:
WiredHome
Date:
Wed Jan 15 12:24:54 2014 +0000
Parent:
22:f6ea795eb541
Child:
24:8ca861acf12d
Commit message:
Some improvements to text APIs, and migration of the test code into the library (behind a #ifdef).

Changed in this revision

Arial12x12.h Show annotated file Show diff for this revision Revisions of this file
GraphicsDisplay.cpp Show annotated file Show diff for this revision Revisions of this file
RA8875.cpp Show annotated file Show diff for this revision Revisions of this file
RA8875.h Show annotated file Show diff for this revision Revisions of this file
WebColors.h Show annotated file Show diff for this revision Revisions of this file
--- a/Arial12x12.h	Sun Jan 12 21:18:47 2014 +0000
+++ b/Arial12x12.h	Wed Jan 15 12:24:54 2014 +0000
@@ -1,4 +1,5 @@
-
+#ifndef ARIAL12X12_H
+#define ARIAL12X12_H
 
 //GLCD FontName : Arial12x12
 //GLCD FontSize : 12 x 12
@@ -104,3 +105,5 @@
     0x07, 0x00, 0x00, 0x20, 0x00, 0x10, 0x00, 0x10, 0x00, 0x20, 0x00, 0x20, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // Code for char ~
     0x08, 0x00, 0x00, 0xFE, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0xFE, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00   // Code for char 
 };
+
+#endif // ARIAL12X12_H
--- a/GraphicsDisplay.cpp	Sun Jan 12 21:18:47 2014 +0000
+++ b/GraphicsDisplay.cpp	Wed Jan 15 12:24:54 2014 +0000
@@ -102,8 +102,9 @@
     0x0C,0x0C,0x0C,0x00,0x0C,0x0C,0x0C,0x00, // |
     0x70,0x18,0x18,0x0E,0x18,0x18,0x70,0x00, // }
     0x3B,0x6E,0x00,0x00,0x00,0x00,0x00,0x00, // ~
-    0x1C,0x36,0x36,0x1C,0x00,0x00,0x00,0x00
-}; // DEL
+    0x1C,0x36,0x36,0x1C,0x00,0x00,0x00,0x00  // DEL
+}; 
+
 
 GraphicsDisplay::GraphicsDisplay(const char *name):TextDisplay(name)
 {
--- a/RA8875.cpp	Sun Jan 12 21:18:47 2014 +0000
+++ b/RA8875.cpp	Wed Jan 15 12:24:54 2014 +0000
@@ -30,12 +30,6 @@
 #define RA8875_DISPLAY_WIDTH  480
 #define RA8875_DISPLAY_HEIGHT 272
 
-/// @TODO what is the size?
-/// If we're using the built-in font, read it from the chip.
-/// If we're using a custom font, get it from the font metrics.
-const int size_x = 16;
-const int size_y = 16;
-
 
 #ifdef PERF_METRICS
 #define PERFORMANCE_RESET performance.reset()
@@ -150,7 +144,7 @@
 unsigned int RA8875::fontwidth(void)
 {
     if (font == NULL)
-        return size_x;
+        return (((ReadCommand(0x22) >> 2) & 0x3) + 1) * 16;
     else
         return width() / font[1];
 }
@@ -158,7 +152,7 @@
 unsigned int RA8875::fontheight(void)
 {
     if (font == NULL)
-        return size_y;
+        return (((ReadCommand(0x22) >> 0) & 0x3) + 1) * 16;
     else
         return height() / font[2];
 }
@@ -198,6 +192,23 @@
     return noerror;
 }
 
+RetCode_t RA8875::SetTextCursorControl(bool visible, bool blink)
+{
+    unsigned char mwcr0 = ReadCommand(0x40) & 0x0F; // retain direction, auto-increase
+    
+    mwcr0 |= 0x80;      // text mode
+    if (visible)
+        mwcr0 |= 0x40;
+    if (blink)
+        mwcr0 |= 0x20;
+    WriteCommand(0x40, mwcr0);      // configure the cursor
+    WriteCommand(0x41, 0x00);       // close the graphics cursor
+    WriteCommand(0x44,0x1f);        //The cursor flashing cycle
+    WriteCommand(0x4e,0x1f);        //The cursor size
+    WriteCommand(0x4f,0x1f);        //The cursor size
+    return noerror;
+}
+
 RetCode_t RA8875::SetTextFont(RA8875::font_t font)
 {
     if (/*font >= RA8875::ISO8859_1 && */ font <= RA8875::ISO8859_4) {
@@ -826,23 +837,22 @@
     WriteCommand(0x89, 0x02);
     wait_ms(1);
     
-    //?
-    WriteCommand(0x10, 0x0C);  //SYSR   bit[4:3]=00 256 color  bit[2:1]=  00 8bit MPU interface, 1x 64k color             1x   16bit
-
-    //?
-    WriteCommand(0x04, 0x82);    //PCLK
+    // System Config Register (SYSR)
+    WriteCommand(0x10, 0x0C);           // 16-bpp (65K colors) color depth, 8-bit interface
+    // Pixel Clock Setting Register (PCSR)
+    WriteCommand(0x04, 0x82);           // PDAT on PCLK falling edge, PCLK = 4 x System Clock
     wait_ms(1);
 
     // Horizontal Settings
-    WriteCommand(0x14, RA8875_DISPLAY_WIDTH/8 - 1);                     //HDWR//Horizontal Display Width Setting Bit[6:0]
+    WriteCommand(0x14, RA8875_DISPLAY_WIDTH/8 - 1); //HDWR//Horizontal Display Width Setting Bit[6:0]
     WriteCommand(0x15, 0x02);                     //HNDFCR//Horizontal Non-Display Period fine tune Bit[3:0]
     WriteCommand(0x16, 0x03);                     //HNDR//Horizontal Non-Display Period Bit[4:0]
     WriteCommand(0x17, 0x01);                     //HSTR//HSYNC Start Position[4:0]
     WriteCommand(0x18, 0x03);                     //HPWR//HSYNC Polarity ,The period width of HSYNC.
 
     // Vertical Settings
-    WriteCommand(0x19, (RA8875_DISPLAY_HEIGHT-1)&0xFF);                     //VDHR0 //Vertical Display Height Bit [7:0]
-    WriteCommand(0x1a, (RA8875_DISPLAY_HEIGHT-1)>>8);                     //VDHR1 //Vertical Display Height Bit [8]
+    WriteCommand(0x19, (RA8875_DISPLAY_HEIGHT-1)&0xFF); //VDHR0 //Vertical Display Height Bit [7:0]
+    WriteCommand(0x1a, (RA8875_DISPLAY_HEIGHT-1)>>8);   //VDHR1 //Vertical Display Height Bit [8]
     WriteCommand(0x1b, 0x0F);                     //VNDR0 //Vertical Non-Display Period Bit [7:0]
     WriteCommand(0x1c, 0x00);                     //VNDR1 //Vertical Non-Display Period Bit [8]
     WriteCommand(0x1d, 0x0e);                     //VSTR0 //VSYNC Start Position[7:0]
@@ -857,3 +867,436 @@
     return noerror;
 }
 
+#ifdef TESTENABLE
+
+//      ______________  ______________  ______________  _______________
+//     /_____   _____/ /  ___________/ /  ___________/ /_____   ______/
+//          /  /      /  /            /  /                  /  /
+//         /  /      /  /___         /  /__________        /  /
+//        /  /      /  ____/        /__________   /       /  /
+//       /  /      /  /                       /  /       /  /
+//      /  /      /  /__________  ___________/  /       /  /
+//     /__/      /_____________/ /_____________/       /__/
+//
+//    Everything from here down is test code.
+
+void ValentineMessage(RA8875 & display, Serial & pc) 
+{
+    pc.printf("Write Sample text\r\n");
+    display.background(BrightRed);
+    display.foreground(White);
+    display.cls();
+    display.SetTextFontControl(NOFILL);
+    for (int i=0; i<20 ; i++) {
+        int sz = rand() & 1 + 1;
+        int rx = rand() % 360 + 0;
+        int ry = rand() % 250 + 0;
+        if (sz == 1)
+            rx /= 2;
+        display.SetTextCursor(rx, ry);
+        display.SetTextFontSize(sz, sz);
+        display.puts("David loves Louize");
+        wait_ms(50);
+    }
+    display.SetTextFontSize(2,2);
+    wait_ms(1000);
+    // Make a heart shape
+    display.ellipse(300, 120, 40, 50, FILL);
+    display.ellipse(370, 120, 40, 50, FILL);
+    display.triangle(265,145, 405,145, 335,230, FILL);
+    wait_ms(2500);
+    display.foreground(Blue);
+    display.puts(300,90, "Be My");
+    wait_ms(500);
+    display.puts(262,118, "Valentine");
+    // put a few things back the way they were
+    display.SetTextFontControl(FILL);
+    display.SetTextFontSize(1,1);
+    display.background(Black);
+}
+
+
+void TextCursorTest(RA8875 & display, Serial & pc)
+{
+    const char * visCursor = "The cursor should be visible for this text.";
+    const char * p;
+    
+    pc.printf("Text Cursor Test\r\n");
+    display.Backlight_u8(255);
+    display.background(Black);
+    display.foreground(Blue);
+    display.cls();
+    display.puts(0,0, "Text Cursor Test.");
+    
+    // visible, non-blinking
+    display.SetTextCursorControl(true, false);
+    display.SetTextCursor(0,40);
+    p = visCursor;
+    while (*p) {
+        display.putc(*p++);
+        wait_ms(100);
+    }
+}
+
+void BacklightTest(RA8875 & display, Serial & pc, float ramptime)
+{
+    pc.printf("Backlight Test - ramp over %f sec.\r\n", ramptime);
+    display.Backlight_u8(0);
+    display.background(Black);
+    display.foreground(Blue);
+    display.cls();
+    display.puts(0,0, "RA8875 Backlight Test - Ramp up.");
+    for (int i=0; i < 255; i++) {
+        display.Backlight_u8(i);
+        wait_ms((ramptime * 1000)/ 256);
+    }
+}
+
+void BacklightTest2(RA8875 & display, Serial & pc)
+{
+    pc.printf("Backlight Test 2\r\n");
+    // Dim it out at the end of the tests.
+    display.foreground(Yellow);
+    display.puts(0,0, "Ramp Backlight down.");
+    // Ramp it off
+    for (int i=255; i != 0; i--) {
+        display.Backlight_u8(i);
+        wait_ms(20);
+    }
+    display.Backlight_u8(0);
+}
+
+void ExternalFontTest(RA8875 & display, Serial & pc)
+{
+    pc.printf("External Font Test\r\n");
+    display.background(Black);
+    display.foreground(Blue);
+    display.cls();
+    display.Backlight(1);
+    display.set_font(Arial12x12);
+    display.puts(0,0,"ABCDEFGHIJKLMNOPWRSTUVWXYZabcdefghijklmnopqrstuvwxyz");
+}
+
+void DOSColorTest(RA8875 & display, Serial & pc)
+{
+    pc.printf("DOS Color Test\r\n");
+    display.background(Black);
+    display.foreground(Blue);
+    display.cls();
+    display.puts(0,0, "DOS Colors - Fore");
+    display.puts(280,0, "Back");
+    display.background(Gray);
+    for (int i=0; i<16; i++) {
+        display.foreground(display.DOSColor(i));
+        display.puts(160, i*16, display.DOSColorNames(i));
+        display.background(Black);
+    }
+    display.foreground(White);
+    for (int i=0; i<16; i++) {
+        display.background(display.DOSColor(i));
+        display.puts(360, i*16, display.DOSColorNames(i));
+        display.foreground(White);
+    }
+}
+
+void WebColorTest(RA8875 & display, Serial & pc)
+{
+    pc.printf("Web Color Test\r\n");
+    display.background(Black);
+    display.foreground(Blue);
+    display.SetWindow(0,0, display.width(), display.height());
+    display.cls();
+    display.puts(0,0, "Web Color Test\r\n");
+    display.SetTextFontSize(1,2);
+    for (int i=0; i<sizeof(WebColors)/sizeof(WebColors[0]); i++) {
+        display.background(WebColors[i]);
+        display.puts(" ");
+        if (i % 36 == 35)
+            display.puts("\r\n");
+    }
+    display.SetTextFontSize(1,1);
+}
+
+void LineTest(RA8875 & display, Serial & pc)
+{
+    int i, x, y, x2, y2;
+
+    pc.printf("Line Test\r\n");
+    display.background(Black);
+    display.foreground(Blue);
+    display.cls();
+    display.puts(0,0, "Line Test");
+    for (i=0; i<16; i++) {
+        // Lines
+        x = rand() % 480;
+        y = rand() % 272;
+        x2 = rand() % 480;
+        y2 = rand() % 272;
+        display.line(x,y, x2,y2, display.DOSColor(i));
+    }
+}
+
+void RectangleTest(RA8875 & display, Serial & pc)
+{
+    int i, x1,y1, x2,y2;
+
+    pc.printf("Rectangle Test\r\n");
+    display.background(Black);
+    display.foreground(Blue);
+    display.cls();
+    display.puts(0,0, "Rectangle Test");
+    for (i=0; i<16; i++) {
+        x1 = rand() % 240;
+        y1 = 50 + rand() % 200;
+        x2 = rand() % 240;
+        y2 = 50 + rand() % 200;
+        display.rect(x1,y1, x2,y2, display.DOSColor(i));
+
+        x1 = 240 + rand() % 240;
+        y1 = 50 + rand() % 200;
+        x2 = 240 + rand() % 240;
+        y2 = 50 + rand() % 200;
+        display.rect(x1,y1, x2,y2, FILL);
+    }
+}
+
+
+void RoundRectTest(RA8875 & display, Serial & pc)
+{
+    unsigned int i, x1,y1, x2,y2, r1,r2;
+
+    pc.printf("Round Rectangle Test\r\n");
+    display.background(Black);
+    display.foreground(Blue);
+    display.cls();
+    display.puts(0,0, "Rounded Rectangle Test");
+    
+    #if 0
+    i = 3;
+    x1 = 30; y1 = 30;
+    x2 = 200; y2 = 100;
+    r1 = 10; r2 = 20;
+    pc.printf("  (%3d,%3d), (%3d,%3d): (%2d,%2d) - %04X\r\n", x1,y1, x2,y2, r1,r2, display.DOSColor(i));
+    display.roundrect(x1,y1, x2,y2, r1,r2, display.DOSColor(i));
+    
+    x1 = 230; y1 = 30;
+    x2 = 400; y2 = 100;
+    r1 = 30; r2 = 34;
+    pc.printf("  (%3d,%3d), (%3d,%3d): (%2d,%2d) - %04X\r\n", x1,y1, x2,y2, r1,r2, display.DOSColor(i));
+    display.roundrect(x1,y1, x2,y2, r1,r2, display.DOSColor(i), NOFILL);
+    #endif
+    
+    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, 5,8, display.DOSColor(i));
+
+        x1 = 240 + 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, FILL);
+    }
+}
+
+void TriangleTest(RA8875 & display, Serial & pc)
+{
+    int i, x1, y1, x2, y2, x3, y3;
+
+    pc.printf("Triangle Test\r\n");
+    display.background(Black);
+    display.foreground(Blue);
+    display.cls();
+    display.puts(0,0, "Triangle Test");
+
+    x1 = 150;
+    y1 = 2;
+    x2 = 190;
+    y2 = 7;
+    x3 = 170;
+    y3 = 16;
+    display.triangle(x1,y1, x2,y2, x3,y3);
+
+    x1 = 200;
+    y1 = 2;
+    x2 = 240;
+    y2 = 7;
+    x3 = 220;
+    y3 = 16;
+    display.filltriangle(x1,y1, x2,y2, x3,y3, BrightRed);
+
+    x1 = 300;
+    y1 = 2;
+    x2 = 340;
+    y2 = 7;
+    x3 = 320;
+    y3 = 16;
+    display.triangle(x1,y1, x2,y2, x3,y3, NOFILL);
+
+    x1 = 400;
+    y1 = 2;
+    x2 = 440;
+    y2 = 7;
+    x3 = 420;
+    y3 = 16;
+    display.triangle(x1,y1, x2,y2, x3,y3, Blue);
+
+    for (i=0; i<16; i++) {
+        x1 = rand() % 240;
+        y1 = 50 + rand() % 200;
+        x2 = rand() % 240;
+        y2 = 50 + rand() % 200;
+        x3 = rand() % 240;
+        y3 = 50 + rand() % 200;
+        display.triangle(x1,y1, x2,y2, x3,y3, display.DOSColor(i));
+        x1 = 240 + rand() % 240;
+        y1 = 50 + rand() % 200;
+        x2 = 240 + rand() % 240;
+        y2 = 50 + rand() % 200;
+        x3 = 240 + rand() % 240;
+        y3 = 50 + rand() % 200;
+        display.triangle(x1,y1, x2,y2, x3,y3, FILL);
+    }
+}
+
+void CircleTest(RA8875 & display, Serial & pc)
+{
+    int i, x, y, r1;
+
+    pc.printf("Circle Test\r\n");
+    display.background(Black);
+    display.foreground(Blue);
+    display.cls();
+    display.puts(0,0, "Circle Test");
+    for (i=0; i<16; i++) {
+        x = 100 + rand() % 100;
+        y = 70 + rand() % 200;
+        r1 = rand() % min(y - 20, 100);
+        //pc.printf("  (%d,%d) - %d\r\n", x,y,r1);
+        display.circle(x,y,r1, display.DOSColor(i));
+
+        x = 300 + rand() % 100;
+        y = 70 + rand() % 200;
+        r1 = rand() % min(y - 20, 100);
+        //pc.printf("  (%d,%d) - %d FILL\r\n", x,y,r1);
+        display.circle(x,y,r1, display.DOSColor(i), FILL);
+    }
+}
+
+void EllipseTest(RA8875 & display, Serial & pc)
+{
+    int i,x,y,r1,r2;
+
+    pc.printf("Ellipse Test\r\n");
+    display.background(Black);
+    display.foreground(Blue);
+    display.cls();
+    display.puts(0,0, "Ellipse Test");
+    for (i=0; i<16; i++) {
+        x = 100 + rand() % 100;
+        y = 70 + rand() % 200;
+        r1 = rand() % min(y - 20, 100);
+        r2 = rand() % min(y - 20, 100);
+        display.ellipse(x,y,r1,r2, display.DOSColor(i));
+
+        x = 300 + rand() % 100;
+        y = 70 + rand() % 200;
+        r1 = rand() % min(y - 20, 100);
+        r2 = rand() % min(y - 20, 100);
+        display.ellipse(x,y,r1,r2, FILL);
+    }
+}
+
+void RunTestSet(RA8875 & lcd, Serial & pc)
+{
+    int q = 0;
+    int automode = 0;
+    const unsigned char modelist[] = "BDWLROTCEbt";   // auto-test in this order.
+
+    while(1) {
+        pc.printf("\r\n"
+                  "B - Backlight up    b - backlight dim\r\n"
+                  "D - DOS Colors      W - Web Colors\r\n"
+                  "t - text cursor                      \r\n"
+                  "L - Lines           F - external Font\r\n"
+                  "R - Rectangles      O - rOund rectangles\r\n"
+                  "T - Triangles                        \r\n"
+                  "C - Circles         E - Ellipses\r\n"
+                  "V - Valentine       r - reset  \r\n"
+                  "A - Auto Test mode                  \r\n"
+                  "> ");
+        if (automode == -1 || pc.readable()) {
+            automode = -1;
+            q = getchar();
+        } else if (automode >= 0) {
+            q = modelist[automode];
+        }
+        switch(q) {
+            case 'A':
+                automode = 0;
+                break;
+            case 'B':
+                BacklightTest(lcd, pc, 2);
+                break;
+            case 'b':
+                BacklightTest2(lcd, pc);
+                break;
+            case 'D':
+                DOSColorTest(lcd, pc);
+                break;
+            case 'W':
+                WebColorTest(lcd, pc);
+                break;
+            case 't':
+                TextCursorTest(lcd, pc);
+                break;
+            case 'F':
+                ExternalFontTest(lcd, pc);
+                break;
+            case 'L':
+                LineTest(lcd, pc);
+                break;
+            case 'R':
+                RectangleTest(lcd, pc);
+                break;
+            case 'O':
+                RoundRectTest(lcd, pc);
+                break;
+            case 'T':
+                TriangleTest(lcd, pc);
+                break;
+            case 'C':
+                CircleTest(lcd, pc);
+                break;
+            case 'E':
+                EllipseTest(lcd, pc);
+                break;
+            case 'V':
+                ValentineMessage(lcd, pc);
+                break;
+            case 'r':
+                pc.printf("Resetting ...\r\n");
+                wait_ms(20);
+                mbed_reset();
+                break;
+            default:
+                printf("huh?\n");
+                break;
+        }
+        if (automode >= 0) {
+            automode++;
+            if (automode >= sizeof(modelist))
+                automode = 0;
+            wait_ms(2000);
+        }
+        wait_ms(200);
+    }
+}
+
+#endif // TESTENABLE
\ No newline at end of file
--- a/RA8875.h	Sun Jan 12 21:18:47 2014 +0000
+++ b/RA8875.h	Wed Jan 15 12:24:54 2014 +0000
@@ -10,7 +10,8 @@
 // graphics commands.
 //#define PERF_METRICS
 
-// What better place for some test code than in here...
+// What better place for some test code than in here and the companion
+// .cpp file. See also the bottom of this file.
 #define TESTENABLE
 
 #define RGB(r,g,b) ( ((r<<8)&0xF800) | ((g<<3)&0x07E0) | (b>>3) )
@@ -131,7 +132,8 @@
     ///
     RA8875(PinName mosi, PinName miso, PinName sclk, PinName csel, PinName reset, const char * name = "lcd");
     
-    /// Destructor doesn't have much to do.
+    /// Destructor doesn't have much to do as this would typically be created
+    /// at startup, and not at runtime.
     //~RA8875();
     
     /// Write a command to the display
@@ -230,6 +232,19 @@
     ///
     RetCode_t SetTextCursor(unsigned int x, unsigned int y);
     
+    /// Configure additional Cursor Control settings.
+    ///
+    /// This API lets you modify other cursor control settings; 
+    /// Cursor visible/hidden, Cursor blink/normal, 
+    /// Cursor I-Beam/underscore/box.
+    ///
+    /// @param visible can be set to true or false (default false)
+    /// @param blink can be set to true or false (default false)
+    /// @param ?
+    /// @returns success/failure code. @see RetCode_t
+    ///
+    RetCode_t SetTextCursorControl(bool visible = false, bool blink = false);
+    
     /// Select the ISO 8859-X font to use next.
     ///
     /// Supported fonts: ISO 8859-1, -2, -3, -4
@@ -839,4 +854,56 @@
 
 //using namespace SW_graphics;
 
+
+#ifdef TESTENABLE
+//      ______________  ______________  ______________  _______________
+//     /_____   _____/ /  ___________/ /  ___________/ /_____   ______/
+//          /  /      /  /            /  /                  /  /
+//         /  /      /  /___         /  /__________        /  /
+//        /  /      /  ____/        /__________   /       /  /
+//       /  /      /  /                       /  /       /  /
+//      /  /      /  /__________  ___________/  /       /  /
+//     /__/      /_____________/ /_____________/       /__/
+
+#include "WebColors.h"
+#include "Arial12x12.h"
+#include <algorithm>
+
+extern "C" void mbed_reset();
+
+/// This activates a small set of tests for the graphics library. 
+///
+/// Call this API and pass it the reference to the display class.
+/// It will then run a series of tests. It accepts interaction via
+/// stdin to switch from automatic test mode to manual, run a specific
+/// test, or to exit the test mode.
+///
+/// @param lcd is a reference to the display class.
+/// @param pc is a reference to a serial interface, typically the USB to PC.
+///
+void RunTestSet(RA8875 & lcd, Serial & pc);
+
+
+// To enable the test code, uncomment this section, or copy the
+// necessary pieces to your "main()".
+//
+// #include "mbed.h"
+// #include "RA8875.h"
+// RA8875 lcd(p5, p6, p7, p12, NC, "tft");    // MOSI, MISO, SCK, /ChipSelect, /reset, name
+// Serial pc(USBTX, USBRX);
+// extern "C" void mbed_reset();
+// int main()
+// {
+//     pc.baud(460800);    // I like a snappy terminal, so crank it up!
+//     pc.printf("\r\nRA8875 Test - Build " __DATE__ " " __TIME__ "\r\n");
+// 
+//     pc.printf("Turning on display\r\n");
+//     lcd.Reset();
+//     lcd.Power(true);  // display power is on, but the backlight is independent
+//     lcd.Backlight(0.5);
+//     RunTestSet(lcd, pc);
+// }
+
+#endif // TESTENABLE
+
 #endif
\ No newline at end of file
--- a/WebColors.h	Sun Jan 12 21:18:47 2014 +0000
+++ b/WebColors.h	Wed Jan 15 12:24:54 2014 +0000
@@ -4,35 +4,35 @@
 
 #include "RA8875.h"
 
-color_t WebColors[256] =
+const color_t WebColors[256] =
     {
-    0x000000, 0x000033, 0x000066, 0x000099, 0x0000CC, 0x0000FF, 0x003300, 0x003333, 
-    0x003366, 0x003399, 0x0033CC, 0x0033FF, 0x006600, 0x006633, 0x006666, 0x006699, 
-    0x0066CC, 0x0066FF, 0x009900, 0x009933, 0x009966, 0x009999, 0x0099CC, 0x0099FF, 
-    0x00CC00, 0x00CC33, 0x00CC66, 0x00CC99, 0x00CCCC, 0x00CCFF, 0x00FF00, 0x00FF33, 
-    0x00FF66, 0x00FF99, 0x00FFCC, 0x00FFFF, 0x330000, 0x330033, 0x330066, 0x330099, 
-    0x3300CC, 0x3300FF, 0x333300, 0x333333, 0x333366, 0x333399, 0x3333CC, 0x3333FF, 
-    0x336600, 0x336633, 0x336666, 0x336699, 0x3366CC, 0x3366FF, 0x339900, 0x339933, 
-    0x339966, 0x339999, 0x3399CC, 0x3399FF, 0x33CC00, 0x33CC33, 0x33CC66, 0x33CC99, 
-    0x33CCCC, 0x33CCFF, 0x33FF00, 0x33FF33, 0x33FF66, 0x33FF99, 0x33FFCC, 0x33FFFF, 
-    0x660000, 0x660033, 0x660066, 0x660099, 0x6600CC, 0x6600FF, 0x663300, 0x663333, 
-    0x663366, 0x663399, 0x6633CC, 0x6633FF, 0x666600, 0x666633, 0x666666, 0x666699, 
-    0x6666CC, 0x6666FF, 0x669900, 0x669933, 0x669966, 0x669999, 0x6699CC, 0x6699FF, 
-    0x66CC00, 0x66CC33, 0x66CC66, 0x66CC99, 0x66CCCC, 0x66CCFF, 0x66FF00, 0x66FF33, 
-    0x66FF66, 0x66FF99, 0x66FFCC, 0x66FFFF, 0x990000, 0x990033, 0x990066, 0x990099, 
-    0x9900CC, 0x9900FF, 0x993300, 0x993333, 0x993366, 0x993399, 0x9933CC, 0x9933FF, 
-    0x996600, 0x996633, 0x996666, 0x996699, 0x9966CC, 0x9966FF, 0x999900, 0x999933, 
-    0x999966, 0x999999, 0x9999CC, 0x9999FF, 0x99CC00, 0x99CC33, 0x99CC66, 0x99CC99, 
-    0x99CCCC, 0x99CCFF, 0x99FF00, 0x99FF33, 0x99FF66, 0x99FF99, 0x99FFCC, 0x99FFFF, 
-    0xCC0000, 0xCC0033, 0xCC0066, 0xCC0099, 0xCC00CC, 0xCC00FF, 0xCC3300, 0xCC3333, 
-    0xCC3366, 0xCC3399, 0xCC33CC, 0xCC33FF, 0xCC6600, 0xCC6633, 0xCC6666, 0xCC6699, 
-    0xCC66CC, 0xCC66FF, 0xCC9900, 0xCC9933, 0xCC9966, 0xCC9999, 0xCC99CC, 0xCC99FF, 
-    0xCCCC00, 0xCCCC33, 0xCCCC66, 0xCCCC99, 0xCCCCCC, 0xCCCCFF, 0xCCFF00, 0xCCFF33, 
-    0xCCFF66, 0xCCFF99, 0xCCFFCC, 0xCCFFFF, 0xFF0000, 0xFF0033, 0xFF0066, 0xFF0099, 
-    0xFF00CC, 0xFF00FF, 0xFF3300, 0xFF3333, 0xFF3366, 0xFF3399, 0xFF33CC, 0xFF33FF, 
-    0xFF6600, 0xFF6633, 0xFF6666, 0xFF6699, 0xFF66CC, 0xFF66FF, 0xFF9900, 0xFF9933, 
-    0xFF9966, 0xFF9999, 0xFF99CC, 0xFF99FF, 0xFFCC00, 0xFFCC33, 0xFFCC66, 0xFFCC99, 
-    0xFFCCCC, 0xFFCCFF, 0xFFFF00, 0xFFFF33, 0xFFFF66, 0xFFFF99, 0xFFFFCC, 0xFFFFFF
+    RGB(0x00,0x00,0x00), RGB(0x00,0x00,0x33), RGB(0x00,0x00,0x66), RGB(0x00,0x00,0x99), RGB(0x00,0x00,0xCC), RGB(0x00,0x00,0xFF), RGB(0x00,0x33,0x00), RGB(0x00,0x33,0x33), 
+    RGB(0x00,0x33,0x66), RGB(0x00,0x33,0x99), RGB(0x00,0x33,0xCC), RGB(0x00,0x33,0xFF), RGB(0x00,0x66,0x00), RGB(0x00,0x66,0x33), RGB(0x00,0x66,0x66), RGB(0x00,0x66,0x99), 
+    RGB(0x00,0x66,0xCC), RGB(0x00,0x66,0xFF), RGB(0x00,0x99,0x00), RGB(0x00,0x99,0x33), RGB(0x00,0x99,0x66), RGB(0x00,0x99,0x99), RGB(0x00,0x99,0xCC), RGB(0x00,0x99,0xFF), 
+    RGB(0x00,0xCC,0x00), RGB(0x00,0xCC,0x33), RGB(0x00,0xCC,0x66), RGB(0x00,0xCC,0x99), RGB(0x00,0xCC,0xCC), RGB(0x00,0xCC,0xFF), RGB(0x00,0xFF,0x00), RGB(0x00,0xFF,0x33), 
+    RGB(0x00,0xFF,0x66), RGB(0x00,0xFF,0x99), RGB(0x00,0xFF,0xCC), RGB(0x00,0xFF,0xFF), RGB(0x33,0x00,0x00), RGB(0x33,0x00,0x33), RGB(0x33,0x00,0x66), RGB(0x33,0x00,0x99), 
+    RGB(0x33,0x00,0xCC), RGB(0x33,0x00,0xFF), RGB(0x33,0x33,0x00), RGB(0x33,0x33,0x33), RGB(0x33,0x33,0x66), RGB(0x33,0x33,0x99), RGB(0x33,0x33,0xCC), RGB(0x33,0x33,0xFF), 
+    RGB(0x33,0x66,0x00), RGB(0x33,0x66,0x33), RGB(0x33,0x66,0x66), RGB(0x33,0x66,0x99), RGB(0x33,0x66,0xCC), RGB(0x33,0x66,0xFF), RGB(0x33,0x99,0x00), RGB(0x33,0x99,0x33), 
+    RGB(0x33,0x99,0x66), RGB(0x33,0x99,0x99), RGB(0x33,0x99,0xCC), RGB(0x33,0x99,0xFF), RGB(0x33,0xCC,0x00), RGB(0x33,0xCC,0x33), RGB(0x33,0xCC,0x66), RGB(0x33,0xCC,0x99), 
+    RGB(0x33,0xCC,0xCC), RGB(0x33,0xCC,0xFF), RGB(0x33,0xFF,0x00), RGB(0x33,0xFF,0x33), RGB(0x33,0xFF,0x66), RGB(0x33,0xFF,0x99), RGB(0x33,0xFF,0xCC), RGB(0x33,0xFF,0xFF), 
+    RGB(0x66,0x00,0x00), RGB(0x66,0x00,0x33), RGB(0x66,0x00,0x66), RGB(0x66,0x00,0x99), RGB(0x66,0x00,0xCC), RGB(0x66,0x00,0xFF), RGB(0x66,0x33,0x00), RGB(0x66,0x33,0x33), 
+    RGB(0x66,0x33,0x66), RGB(0x66,0x33,0x99), RGB(0x66,0x33,0xCC), RGB(0x66,0x33,0xFF), RGB(0x66,0x66,0x00), RGB(0x66,0x66,0x33), RGB(0x66,0x66,0x66), RGB(0x66,0x66,0x99), 
+    RGB(0x66,0x66,0xCC), RGB(0x66,0x66,0xFF), RGB(0x66,0x99,0x00), RGB(0x66,0x99,0x33), RGB(0x66,0x99,0x66), RGB(0x66,0x99,0x99), RGB(0x66,0x99,0xCC), RGB(0x66,0x99,0xFF), 
+    RGB(0x66,0xCC,0x00), RGB(0x66,0xCC,0x33), RGB(0x66,0xCC,0x66), RGB(0x66,0xCC,0x99), RGB(0x66,0xCC,0xCC), RGB(0x66,0xCC,0xFF), RGB(0x66,0xFF,0x00), RGB(0x66,0xFF,0x33), 
+    RGB(0x66,0xFF,0x66), RGB(0x66,0xFF,0x99), RGB(0x66,0xFF,0xCC), RGB(0x66,0xFF,0xFF), RGB(0x99,0x00,0x00), RGB(0x99,0x00,0x33), RGB(0x99,0x00,0x66), RGB(0x99,0x00,0x99), 
+    RGB(0x99,0x00,0xCC), RGB(0x99,0x00,0xFF), RGB(0x99,0x33,0x00), RGB(0x99,0x33,0x33), RGB(0x99,0x33,0x66), RGB(0x99,0x33,0x99), RGB(0x99,0x33,0xCC), RGB(0x99,0x33,0xFF), 
+    RGB(0x99,0x66,0x00), RGB(0x99,0x66,0x33), RGB(0x99,0x66,0x66), RGB(0x99,0x66,0x99), RGB(0x99,0x66,0xCC), RGB(0x99,0x66,0xFF), RGB(0x99,0x99,0x00), RGB(0x99,0x99,0x33), 
+    RGB(0x99,0x99,0x66), RGB(0x99,0x99,0x99), RGB(0x99,0x99,0xCC), RGB(0x99,0x99,0xFF), RGB(0x99,0xCC,0x00), RGB(0x99,0xCC,0x33), RGB(0x99,0xCC,0x66), RGB(0x99,0xCC,0x99), 
+    RGB(0x99,0xCC,0xCC), RGB(0x99,0xCC,0xFF), RGB(0x99,0xFF,0x00), RGB(0x99,0xFF,0x33), RGB(0x99,0xFF,0x66), RGB(0x99,0xFF,0x99), RGB(0x99,0xFF,0xCC), RGB(0x99,0xFF,0xFF), 
+    RGB(0xCC,0x00,0x00), RGB(0xCC,0x00,0x33), RGB(0xCC,0x00,0x66), RGB(0xCC,0x00,0x99), RGB(0xCC,0x00,0xCC), RGB(0xCC,0x00,0xFF), RGB(0xCC,0x33,0x00), RGB(0xCC,0x33,0x33), 
+    RGB(0xCC,0x33,0x66), RGB(0xCC,0x33,0x99), RGB(0xCC,0x33,0xCC), RGB(0xCC,0x33,0xFF), RGB(0xCC,0x66,0x00), RGB(0xCC,0x66,0x33), RGB(0xCC,0x66,0x66), RGB(0xCC,0x66,0x99), 
+    RGB(0xCC,0x66,0xCC), RGB(0xCC,0x66,0xFF), RGB(0xCC,0x99,0x00), RGB(0xCC,0x99,0x33), RGB(0xCC,0x99,0x66), RGB(0xCC,0x99,0x99), RGB(0xCC,0x99,0xCC), RGB(0xCC,0x99,0xFF), 
+    RGB(0xCC,0xCC,0x00), RGB(0xCC,0xCC,0x33), RGB(0xCC,0xCC,0x66), RGB(0xCC,0xCC,0x99), RGB(0xCC,0xCC,0xCC), RGB(0xCC,0xCC,0xFF), RGB(0xCC,0xFF,0x00), RGB(0xCC,0xFF,0x33), 
+    RGB(0xCC,0xFF,0x66), RGB(0xCC,0xFF,0x99), RGB(0xCC,0xFF,0xCC), RGB(0xCC,0xFF,0xFF), RGB(0xFF,0x00,0x00), RGB(0xFF,0x00,0x33), RGB(0xFF,0x00,0x66), RGB(0xFF,0x00,0x99), 
+    RGB(0xFF,0x00,0xCC), RGB(0xFF,0x00,0xFF), RGB(0xFF,0x33,0x00), RGB(0xFF,0x33,0x33), RGB(0xFF,0x33,0x66), RGB(0xFF,0x33,0x99), RGB(0xFF,0x33,0xCC), RGB(0xFF,0x33,0xFF), 
+    RGB(0xFF,0x66,0x00), RGB(0xFF,0x66,0x33), RGB(0xFF,0x66,0x66), RGB(0xFF,0x66,0x99), RGB(0xFF,0x66,0xCC), RGB(0xFF,0x66,0xFF), RGB(0xFF,0x99,0x00), RGB(0xFF,0x99,0x33), 
+    RGB(0xFF,0x99,0x66), RGB(0xFF,0x99,0x99), RGB(0xFF,0x99,0xCC), RGB(0xFF,0x99,0xFF), RGB(0xFF,0xCC,0x00), RGB(0xFF,0xCC,0x33), RGB(0xFF,0xCC,0x66), RGB(0xFF,0xCC,0x99), 
+    RGB(0xFF,0xCC,0xCC), RGB(0xFF,0xCC,0xFF), RGB(0xFF,0xFF,0x00), RGB(0xFF,0xFF,0x33), RGB(0xFF,0xFF,0x66), RGB(0xFF,0xFF,0x99), RGB(0xFF,0xFF,0xCC), RGB(0xFF,0xFF,0xFF)
     };
 
 #endif // WEBCOLORS_H