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:
37:f19b7e7449dc
Parent:
32:0e4f2ae512e2
Child:
38:38d503b4fad6
--- a/RA8875.cpp	Sat Jan 25 00:00:02 2014 +0000
+++ b/RA8875.cpp	Sat Jan 25 19:47:33 2014 +0000
@@ -143,7 +143,7 @@
     return data;
 }
 
-unsigned int RA8875::fontwidth(void)
+dim_t RA8875::fontwidth(void)
 {
     if (font == NULL)
         return (((ReadCommand(0x22) >> 2) & 0x3) + 1) * 16;
@@ -151,7 +151,7 @@
         return font[1];
 }
 
-unsigned int RA8875::fontheight(void)
+dim_t RA8875::fontheight(void)
 {
     if (font == NULL)
         return (((ReadCommand(0x22) >> 0) & 0x3) + 1) * 16;
@@ -159,7 +159,7 @@
         return font[2];
 }
 
-RetCode_t RA8875::locate(unsigned int column, unsigned int row)
+RetCode_t RA8875::locate(textloc_t column, textloc_t row)
 {
     return SetTextCursor(column * fontwidth(), row * fontheight());
 }
@@ -184,7 +184,7 @@
     return (ReadCommand(0x19) | (ReadCommand(0x1A) << 8)) + 1;
 }
 
-RetCode_t RA8875::SetTextCursor(unsigned int x, unsigned int y)
+RetCode_t RA8875::SetTextCursor(loc_t x, loc_t y)
 {
     cursor_x = x; cursor_y = y;     // for non-internal fonts
     WriteCommand(0x2A, x & 0xFF);
@@ -194,7 +194,7 @@
     return noerror;
 }
 
-unsigned int RA8875::GetTextCursor_Y(void)
+loc_t RA8875::GetTextCursor_Y(void)
 {
     if (font == NULL)
         return ReadCommand(0x2C) | (ReadCommand(0x2D) << 8);
@@ -202,7 +202,7 @@
         return cursor_y;
 }
 
-unsigned int RA8875::GetTextCursor_X(void)
+loc_t RA8875::GetTextCursor_X(void)
 {
     if (font == NULL)
         return ReadCommand(0x2A) | (ReadCommand(0x2B) << 8);
@@ -314,6 +314,7 @@
             cursor_y += font[2];
         } else {
             int advance = character(cursor_x, cursor_y, c);     // advance tells us how many pixels we advanced
+            //INFO("x,y,advance %d,%d,%d", cursor_x, cursor_y, advance);
             if (advance) {
                 cursor_x += advance;
                 if (cursor_x >= width()) {
@@ -339,12 +340,12 @@
             WriteCommand(0x40, 0x80 | mwcr0);    // Put in Text mode if not already
         }
         if (c == '\r') {
-            unsigned int x;
+            loc_t x;
             x = ReadCommand(0x30) | (ReadCommand(0x31) << 8);   // Left edge of active window
             WriteCommand(0x2A, x & 0xFF);
             WriteCommand(0x2B, x >> 8);
         } else if (c == '\n') {
-            unsigned int y;
+            loc_t y;
             y = ReadCommand(0x2C) | (ReadCommand(0x2D) << 8);   // current y location
             y += fontheight();
             if (y > height())               // @TODO after bottom of active window, then scroll window?
@@ -377,12 +378,12 @@
 
 RetCode_t RA8875::putp(color_t pixel)
 {
+    WriteData(pixel >> 8);
     WriteData(pixel & 0xFF);
-    WriteData(pixel >> 8);
     return noerror;   
 }
 
-void RA8875::puts(unsigned int x, unsigned int y, const char * string)
+void RA8875::puts(loc_t x, loc_t y, const char * string)
 {
     SetTextCursor(x,y);
     puts(string);
@@ -391,9 +392,13 @@
 void RA8875::puts(const char * string)
 {
     unsigned char mwcr0 = ReadCommand(0x40);
-                
-    if ((mwcr0 & 0x80) == 0x00)
-        WriteCommand(0x40,0x80);    // Put in Text mode if not already
+    
+    if (font == NULL) {
+        if ((mwcr0 & 0x80) == 0x00)
+            WriteCommand(0x40,0x80);    // Put in Text mode if not already
+    } else {
+        _StartGraphicsStream();
+    }
     if (*string != '\0') {
         #if 1
         while (*string) {           // @TODO calling individual _putc is slower... optimizations?
@@ -411,9 +416,11 @@
         select(false);
         #endif
     }
+    if (font)
+        _EndGraphicsStream();
 }
 
-RetCode_t RA8875::SetGraphicsCursor(uint16_t x, uint16_t y)
+RetCode_t RA8875::SetGraphicsCursor(loc_t x, loc_t y)
 {
     WriteCommand(0x46, x & 0xFF);
     WriteCommand(0x47, x >> 8);
@@ -422,8 +429,9 @@
     return noerror;
 }
 
-RetCode_t RA8875::window(unsigned int x, unsigned int y, unsigned int width, unsigned int height)
+RetCode_t RA8875::window(loc_t x, loc_t y, dim_t width, dim_t height)
 {
+    GraphicsDisplay::window(x,y, width,height);
     WriteCommand(0x30, x & 0xFF);   // HSAW0
     WriteCommand(0x31, x >> 8);     // HSAW1
     WriteCommand(0x32, y & 0xFF);    // VSAW0
@@ -432,6 +440,7 @@
     WriteCommand(0x35, (x+width-1) >> 8);    // HEAW1
     WriteCommand(0x36, (y+height-1) & 0xFF); // VEAW0
     WriteCommand(0x37, (y+height-1) >> 8);   // VEAW1
+    SetGraphicsCursor(x,y);
     return noerror;
 }
 
@@ -439,7 +448,7 @@
 {
     PERFORMANCE_RESET;
     clsw(FULLWINDOW);
-    cursor_x = cursor_y = 0;
+    SetTextCursor(0,0);
     REGISTERPERFORMANCE(PRF_CLS);
     return noerror;
 }
@@ -454,13 +463,14 @@
     return noerror;
 }
 
-RetCode_t RA8875::pixel(unsigned int x, unsigned int y, color_t color)
+RetCode_t RA8875::pixel(loc_t x, loc_t y, color_t color)
 {
+    INFO("pixel(%d,%d, %04X)", x,y, color);
     foreground(color);
     return pixel(x,y);
 }
 
-RetCode_t RA8875::pixel(unsigned int x, unsigned int y)
+RetCode_t RA8875::pixel(loc_t x, loc_t y)
 {
     RetCode_t ret;
     
@@ -468,7 +478,7 @@
     color_t color = GetForeColor();
     WriteCommand(0x40,0x00);    // Graphics write mode
     SetGraphicsCursor(x, y);
-    WriteCommand(0x02);         //start data write
+    WriteCommand(0x02);         // start data write
     WriteData(color & 0xFF);
     WriteData(color >> 8);
     ret = noerror;
@@ -476,13 +486,13 @@
     return ret;
 }
 
-RetCode_t RA8875::line(unsigned int x1, unsigned int y1, unsigned int x2, unsigned int y2, color_t color)
+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(unsigned int x1, unsigned int y1, unsigned int x2, unsigned int y2)
+RetCode_t RA8875::line(loc_t x1, loc_t y1, loc_t x2, loc_t y2)
 {
     PERFORMANCE_RESET;
     WriteCommand(0x91, x1 & 0xFF);
@@ -503,20 +513,20 @@
     return noerror;
 }
 
-RetCode_t RA8875::fillrect(unsigned int x1, unsigned int y1, unsigned int x2, unsigned int y2, 
+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(unsigned int x1, unsigned int y1, unsigned int x2, unsigned int y2, 
+RetCode_t RA8875::rect(loc_t x1, loc_t y1, loc_t x2, loc_t y2, 
     color_t color, fill_t fillit)
 {
     foreground(color);
     return rect(x1,y1,x2,y2,fillit);
 }
 
-RetCode_t RA8875::rect(unsigned int x1, unsigned int y1, unsigned int x2, unsigned int y2, 
+RetCode_t RA8875::rect(loc_t x1, loc_t y1, loc_t x2, loc_t y2, 
     fill_t fillit)
 {
     PERFORMANCE_RESET;
@@ -548,22 +558,22 @@
     return noerror;
 }
 
-RetCode_t RA8875::fillroundrect(unsigned int x1, unsigned int y1, unsigned int x2, unsigned int y2, 
-    unsigned int radius1, unsigned int radius2, color_t color, fill_t fillit)
+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)
 {
     foreground(color);
     return roundrect(x1,y1,x2,y2,radius1,radius2,fillit);
 }
 
-RetCode_t RA8875::roundrect(unsigned int x1, unsigned int y1, unsigned int x2, unsigned int y2, 
-    unsigned int radius1, unsigned int radius2, color_t color, fill_t 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)
 {
     foreground(color);
     return roundrect(x1,y1,x2,y2,radius1,radius2,fillit);
 }
 
-RetCode_t RA8875::roundrect(unsigned int x1, unsigned int y1, unsigned int x2, unsigned int y2, 
-    unsigned int radius1, unsigned int radius2, fill_t 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)
 {
     RetCode_t ret = noerror;
     
@@ -610,8 +620,8 @@
     return ret;
 }
 
-RetCode_t RA8875::triangle(unsigned int x1, unsigned int y1, unsigned int x2, unsigned int y2, 
-    unsigned int x3, unsigned int y3, color_t color, fill_t fillit)
+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)
 {
     RetCode_t ret;
     
@@ -620,8 +630,8 @@
     return ret;
 }
 
-RetCode_t RA8875::filltriangle(unsigned int x1, unsigned int y1, unsigned int x2, unsigned int y2, 
-    unsigned int x3, unsigned int y3, color_t color, fill_t fillit)
+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)
 {
     RetCode_t ret;
 
@@ -630,8 +640,8 @@
     return ret;
 }
 
-RetCode_t RA8875::triangle(unsigned int x1, unsigned int y1 ,unsigned int x2, unsigned int y2, 
-    unsigned int x3, unsigned int y3, fill_t fillit)
+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)
 {
     RetCode_t ret = noerror;
     
@@ -666,21 +676,21 @@
     return ret;
 }
 
-RetCode_t RA8875::circle(unsigned int x, unsigned int y, unsigned int radius, 
+RetCode_t RA8875::circle(loc_t x, loc_t y, dim_t radius, 
     color_t color, fill_t fillit)
 {
     foreground(color);
     return circle(x,y,radius,fillit);
 }
 
-RetCode_t RA8875::fillcircle(unsigned int x, unsigned int y, unsigned int radius, 
+RetCode_t RA8875::fillcircle(loc_t x, loc_t y, dim_t radius, 
     color_t color, fill_t fillit)
 {
     foreground(color);
     return circle(x,y,radius,fillit);
 }
 
-RetCode_t RA8875::circle(unsigned int x, unsigned int y, unsigned int radius, fill_t fillit)
+RetCode_t RA8875::circle(loc_t x, loc_t y, dim_t radius, fill_t fillit)
 {
     RetCode_t ret = noerror;
     
@@ -708,19 +718,19 @@
     return ret;
 }
 
-RetCode_t RA8875::ellipse(unsigned int x, unsigned int y, unsigned int radius1, unsigned int radius2, color_t color, fill_t fillit)
+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(unsigned int x, unsigned int y, unsigned int radius1, unsigned int radius2, color_t color, fill_t 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(unsigned int x, unsigned int y, unsigned int radius1, unsigned int radius2, fill_t fillit)
+RetCode_t RA8875::ellipse(loc_t x, loc_t y, dim_t radius1, dim_t radius2, fill_t fillit)
 {
     RetCode_t ret = noerror;
     
@@ -811,9 +821,11 @@
     return Backlight_u8(b);
 }
 
-
 RetCode_t RA8875::set_font(const unsigned char * _font)
 {
+    if (font && ! _font) {
+        SetTextCursor(cursor_x, cursor_y);  // soft-font cursor -> hw cursor
+    }
     font = _font;
     GraphicsDisplay::set_font(_font);
     return noerror;     // trusting them, but it might be good to put some checks in here...
@@ -821,6 +833,7 @@
 
 RetCode_t RA8875::background(color_t color)
 {
+    GraphicsDisplay::background(color);
     WriteCommand(0x60, (color>>11));                  // BGCR0
     WriteCommand(0x61, (unsigned char)(color>>5));    // BGCR0
     WriteCommand(0x62, (unsigned char)(color));       // BGCR0
@@ -829,29 +842,32 @@
 
 RetCode_t RA8875::background(unsigned char r, unsigned char g, unsigned char b)
 {
-    WriteCommand(0x60, r);
-    WriteCommand(0x61, g);
-    WriteCommand(0x62, b);
+    background(RGB(r,g,b));
+//    WriteCommand(0x60, r);
+//    WriteCommand(0x61, g);
+//    WriteCommand(0x62, b);
     return noerror;
 }
 
 RetCode_t RA8875::foreground(color_t color)
 {
+    GraphicsDisplay::foreground(color);
     WriteCommand(0x63, (unsigned char)(color>>11));
     WriteCommand(0x64, (unsigned char)(color>>5));
     WriteCommand(0x65, (unsigned char)(color));
     return noerror;
 }
 
-RetCode_t RA8875::foreground(unsigned char setR, unsigned char setG, unsigned char setB)
+RetCode_t RA8875::foreground(unsigned char r, unsigned char g, unsigned char b)
 {
-    WriteCommand(0x63, setR);
-    WriteCommand(0x64, setG);
-    WriteCommand(0x65, setB);
+    foreground(RGB(r,g,b));
+//    WriteCommand(0x63, r);
+//    WriteCommand(0x64, g);
+//    WriteCommand(0x65, b);
     return noerror;
 }
 
-unsigned int RA8875::GetForeColor(void)
+color_t RA8875::GetForeColor(void)
 {
     color_t color;
     
@@ -921,15 +937,15 @@
 RetCode_t RA8875::init(void)
 {
     Backlight_u8(0);
-    WriteCommand(0x88, 0x0a);               // PLLC1 - Phase Lock Loop registers
+    WriteCommand(0x88, 0x0a);                   // PLLC1 - Phase Lock Loop registers
     wait_ms(1);
     WriteCommand(0x89, 0x02);
     wait_ms(1);
     
     // System Config Register (SYSR)
-    WriteCommand(0x10, 0x0C);           // 16-bpp (65K colors) color depth, 8-bit interface
+    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
+    WriteCommand(0x04, 0x82);                   // PDAT on PCLK falling edge, PCLK = 4 x System Clock
     wait_ms(1);
 
     // Horizontal Settings
@@ -949,7 +965,7 @@
     WriteCommand(0x1f, 0x01);                     //VPWR //VSYNC Polarity ,VSYNC Pulse Width[6:0]
 
     // Clear ram image
-    window(0,0, width(), height());          // Initialize to full screen
+    window(0,0, width(), height());             // Initialize to full screen
     SetTextCursorControl();
     foreground(Blue);
     background(Black);
@@ -959,6 +975,9 @@
 
 #ifdef TESTENABLE
 
+#include "Arial12x12.h"
+#include "Small_6.h"
+
 //      ______________  ______________  ______________  _______________
 //     /_____   _____/ /  ___________/ /  ___________/ /_____   ______/
 //          /  /      /  /            /  /                  /  /
@@ -972,10 +991,10 @@
 
 void TextCursorTest(RA8875 & display, Serial & pc)
 {
-    const char * iCursor = "The I-Beam cursor should be visible for this text, but it should not be blinking while writing this text.\r\n";
-    const char * uCursor = "The Underscore cursor should be visible for this text, but it should not be blinking while writing this text.\r\n";
-    const char * bCursor = "The Block cursor should be visible for this text, but it should not be blinking while writing this text.\r\n";
-    const char * bbCursor = "The Blinking Block cursor should be visible for this text, and it should be blinking while writing this text.\r\n";
+    const char * iCursor = "The I-Beam cursor should be visible for this text.\r\n";
+    const char * uCursor = "The Underscore cursor should be visible for this text.\r\n";
+    const char * bCursor = "The Block cursor should be visible for this text.\r\n";
+    const char * bbCursor = "The Blinking Block cursor should be visible for this text.\r\n";
     const char * p;
     
     pc.printf("Text Cursor Test\r\n");
@@ -1032,7 +1051,7 @@
     for (int i=0; i < 255; i++) {
         unsigned int w = (ramptime * 1000)/ 256;
         sprintf(buf, "%3d, %4d", i, w);
-        display.puts(0,40,buf);
+        display.puts(100,100,buf);
         display.Backlight_u8(i);
         wait_ms(w);
     }
@@ -1042,7 +1061,7 @@
 {
     pc.printf("Backlight Test 2\r\n");
     // Dim it out at the end of the tests.
-    display.foreground(Yellow);
+    display.foreground(Blue);
     display.puts(0,0, "Ramp Backlight down.");
     // Ramp it off
     for (int i=255; i != 0; i--) {
@@ -1059,8 +1078,17 @@
     display.foreground(Blue);
     display.cls();
     display.Backlight(1);
+    display.puts(0,0, "External Font Test.");
+
+    display.set_font(Small_6);
+    display.puts(0,30, "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\r\n");    
+
     display.set_font(Arial12x12);
-    display.puts(0,0,"ABCDEFGHIJKLMNOPWRSTUVWXYZabcdefghijklmnopqrstuvwxyz");
+    display.puts("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\r\n");
+    display.set_font();     // restore to internal
+    
+    display.puts("Normal font again.");
+    //display.window(0,0, display.width(), display.height());
 }
 
 void DOSColorTest(RA8875 & display, Serial & pc)
@@ -1103,6 +1131,24 @@
     display.SetTextFontSize(1,1);
 }
 
+void PixelTest(RA8875 & display, Serial & pc)
+{
+    int i, c, x, y;
+
+    pc.printf("Pixel Test\r\n");
+    display.background(Black);
+    display.foreground(Blue);
+    display.cls();
+    display.puts(0,0, "Pixel Test");
+    for (i=0; i<1000; i++) {
+        x = rand() % 480;
+        y = 16 + rand() % (272-16);
+        c = rand() % 16;
+        //pc.printf("  (%d,%d) - %d\r\n", x,y,r1);
+        display.pixel(x,y, display.DOSColor(c));
+    }
+}
+
 void LineTest(RA8875 & display, Serial & pc)
 {
     int i, x, y, x2, y2;
@@ -1146,10 +1192,9 @@
     }
 }
 
-
 void RoundRectTest(RA8875 & display, Serial & pc)
 {
-    unsigned int i, x1,y1, x2,y2, r1,r2;
+    loc_t i, x1,y1, x2,y2, r1,r2;
 
     pc.printf("Round Rectangle Test\r\n");
     display.background(Black);
@@ -1284,26 +1329,40 @@
     }
 }
 
+void TestGraphicsBitmap(RA8875 & display, Serial & pc)
+{
+    LocalFileSystem local("local");
+    display.background(Black);
+    display.foreground(Blue);
+    display.cls();
+    display.puts(0,0, "Graphics Test, loading /local/TestPat.bmp");
+    wait(3);
+
+    int r = display.RenderBitmapFile(0,0, "/local/TestPat.bmp");
+}
+
 void RunTestSet(RA8875 & lcd, Serial & pc)
 {
     int q = 0;
     int automode = 0;
-    const unsigned char modelist[] = "BDWLROTCEbt";   // auto-test in this order.
+    const unsigned char modelist[] = "BDWtGLFROTPCEb";   // 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"
+                  "t - text cursor     G - Graphics Bitmap\r\n"
                   "L - Lines           F - external Font\r\n"
                   "R - Rectangles      O - rOund rectangles\r\n"
-                  "T - Triangles                        \r\n"
+                  "T - Triangles       P - Pixels  \r\n"
                   "C - Circles         E - Ellipses\r\n"
                   "A - Auto Test mode  r - reset  \r\n"
                   "> ");
         if (automode == -1 || pc.readable()) {
             automode = -1;
-            q = getchar();
+            q = pc.getc();
+            while (pc.readable())
+                pc.getc();
         } else if (automode >= 0) {
             q = modelist[automode];
         }
@@ -1341,6 +1400,12 @@
             case 'T':
                 TriangleTest(lcd, pc);
                 break;
+            case 'P':
+                PixelTest(lcd, pc);
+                break;
+            case 'G':
+                TestGraphicsBitmap(lcd, pc);
+                break;
             case 'C':
                 CircleTest(lcd, pc);
                 break;