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:
178:ae472eb22740
Parent:
176:4ab96d33a8ec
Child:
181:0032d1b8f5d4
--- a/RA8875.cpp	Wed Jul 17 03:02:31 2019 +0000
+++ b/RA8875.cpp	Sun Jul 28 01:33:02 2019 +0000
@@ -192,6 +192,7 @@
     , cs(csel)
     , res(reset)
 {
+    INFO("RA8875");
     touchInfo = (touchInfo_T *)malloc(RESISTIVE_TOUCH_POINTS * sizeof(touchInfo_T));
     if (touchInfo)
         useTouchPanel = TP_RES;
@@ -218,11 +219,13 @@
     , cs(csel)
     , res(reset)
 {
+    INFO("RA8875");
     tpFQFN = NULL;
     tpCalMessage = NULL;
     m_irq = new InterruptIn(irq);
     m_i2c = new I2C(sda, scl);
-
+    INFO("m_i2c = %p", m_i2c);
+    
     // Cap touch panel config
     touchInfo = (touchInfo_T *)malloc(FT5206_TOUCH_POINTS * sizeof(touchInfo_T));
     if (touchInfo)
@@ -241,7 +244,6 @@
 
     // Interrupt
     m_irq->mode(PullUp);
-    m_irq->enable_irq();
     #if MBED_VERSION >= MBED_ENCODE_VERSION(5,8,0)
     eventThread.start(callback(&queue, &EventQueue::dispatch_forever));
     m_irq->fall(queue.event(callback(this, &RA8875::TouchPanelISR)));
@@ -250,7 +252,9 @@
     #else
     m_irq->fall(this, &RA8875::TouchPanelISR);
     #endif
+    m_irq->enable_irq();
     TouchPanelInit();
+    INFO("RA8875 end.");
 }
 
 
@@ -263,6 +267,7 @@
     , cs(csel)
     , res(reset)
 {
+    INFO("RA8875");
     tpFQFN = NULL;
     tpCalMessage = NULL;
     m_irq = new InterruptIn(irq);
@@ -307,6 +312,7 @@
 
 RetCode_t RA8875::init(int width, int height, int color_bpp, uint8_t poweron, bool keypadon, bool touchscreenon)
 {
+    INFO("RA8875::init()");
     font = NULL;                                // no external font, use internal.
     pKeyMap = DefaultKeyMap;                    // set default key map
     _select(false);                             // deselect the display
@@ -397,12 +403,14 @@
     if (touchscreenon) {
         if (useTouchPanel == TP_NONE)
             useTouchPanel = TP_RES;
-        TouchPanelInit();
+        if (useTouchPanel == TP_RES)
+            TouchPanelInit();       // only init again if resistive (due to HW reset applied above).
     }
 #ifdef PERF_METRICS
     performance.start();
     ClearPerformance();
 #endif
+    INFO("RA8875::init() end");
     return noerror;
 }
 
@@ -1371,6 +1379,7 @@
 {
     RetCode_t ret;
 
+    INFO("cls()");
     PERFORMANCE_RESET;
     if (layers == 0) {
         ret = clsw(FULLWINDOW);
@@ -1389,7 +1398,7 @@
         SelectDrawingLayer(prevLayer);
     }
     ret = SetTextCursor(0,0);
-    ret = locate(0,0);
+    //ret = locate(0,0);
     REGISTERPERFORMANCE(PRF_CLS);
     return ret;
 }
@@ -1397,6 +1406,7 @@
 
 RetCode_t RA8875::clsw(RA8875::Region_t region)
 {
+    INFO("clsw()");
     PERFORMANCE_RESET;
     WriteCommand(RA8875_MCLR, (region == ACTIVEWINDOW) ? 0xC0 : 0x80);
     if (!_WaitWhileReg(0x8E, 0x80)) {
@@ -1609,23 +1619,76 @@
 
 RetCode_t RA8875::ThickLine(point_t p1, point_t p2, dim_t thickness, color_t color)
 {
+    INFO("ThickLine()");
     if (thickness == 1) {
         line(p1,p2, color);
     } else {
-        int dx = abs(p2.x-p1.x), sx = p1.x<p2.x ? 1 : -1;
-        int dy = abs(p2.y-p1.y), sy = p1.y<p2.y ? 1 : -1;
-        int err = (dx>dy ? dx : -dy)/2, e2;
-        
-        for (;;) {
-            fillcircle(p1.x, p1.y, thickness/2, color);
-            if (p1.x==p2.x && p1.y==p2.y) 
-                break;
-            e2 = err;
-            if (e2 >-dx) 
-                { err -= dy; p1.x += sx; }
-            if (e2 < dy) 
-                { err += dx; p1.y += sy; }
-        }        
+        if (p1.x == p2.x) {
+            // vertical
+            fillcircle(p1, thickness/2, color);
+            fillcircle(p2, thickness/2, color);
+            fillrect(p1.x-thickness/2,p1.y, p2.x+thickness/2,p2.y, color);
+        } else if (p1.y == p2.y) {
+            // horizontal
+            fillcircle(p1, thickness/2, color);
+            fillcircle(p2, thickness/2, color);
+            fillrect(p1.x,p1.y-thickness/2, p2.x,p2.y+thickness/2, color);
+        } else {
+            // some diagonal, drawn rather slowly with filled circles
+            // @todo draw the end-points with circles, then draw the diagonal
+            //      with 2 triangles. 
+            #if 1  // New Faster method
+            //Round-caps
+            fillcircle(p1, thickness/2, color);
+            fillcircle(p2, thickness/2, color);
+            // Compute the perpendicular points to draw the triangles
+            //              +           fillTriangle: p1a,p1b,p2a
+            //            /   + p1a                   p1a,p2a,p2b
+            //           +  +p1+ .  .   .   .    .
+            //       p1b  +   /  .      angle
+            //              +        . 
+            //                           .
+            //
+            //                                   .        +
+            //                                          /   + p2a
+            //                                         +  +p2+
+            //                                     p2b  +   /
+            //                                            +
+            point_t pTri[4];
+            float slope = (p2.y - p1.y) / (p2.x - p1.x);
+            slope = -1/slope;
+            //centerline
+            //line(p1,p2,color);
+            float dx = (thickness/2 / sqrt(thickness/2 + (slope * slope))); 
+            float dy = slope * dx;
+            pTri[0].x = p1.x + dx;
+            pTri[0].y = p1.y + dy;
+            pTri[1].x = p1.x - dx;
+            pTri[1].y = p1.y - dy;
+            pTri[2].x = p2.x + dx;
+            pTri[2].y = p2.y + dy;
+            pTri[3].x = p2.x - dx;
+            pTri[3].y = p2.y - dy;
+            filltriangle(pTri[0],pTri[1],pTri[3], color);
+            filltriangle(pTri[0],pTri[2],pTri[3], color);
+            #else // old slower method
+            // Draw with a lot of overlapping circles
+            int dx = abs(p2.x-p1.x), sx = p1.x<p2.x ? 1 : -1;
+            int dy = abs(p2.y-p1.y), sy = p1.y<p2.y ? 1 : -1;
+            int err = (dx>dy ? dx : -dy)/2, e2;
+            
+            for (;;) {
+                fillcircle(p1.x, p1.y, thickness/2, color);
+                if (p1.x==p2.x && p1.y==p2.y) 
+                    break;
+                e2 = err;
+                if (e2 >-dx) 
+                    { err -= dy; p1.x += sx; }
+                if (e2 < dy) 
+                    { err += dx; p1.y += sy; }
+            }
+            #endif
+        }
     }
     return noerror;
 }
@@ -1729,6 +1792,7 @@
 {
     RetCode_t ret = noerror;
 
+    INFO("roundrect()");
     PERFORMANCE_RESET;
     if (x1 < 0 || x1 >= screenwidth || x2 < 0 || x2 >= screenwidth 
     || y1 < 0 || y1 >= screenheight || y2 < 0 || y2 >= screenheight) {
@@ -1769,6 +1833,15 @@
 //
 // triangle functions
 //
+RetCode_t RA8875::filltriangle(point_t p1, point_t p2, point_t p3, color_t color, fill_t fillit)
+{
+    return filltriangle(p1.x,p1.y, p2.x,p2.y, p3.x,p3.y, color, fillit);
+}
+
+RetCode_t RA8875::triangle(point_t p1, point_t p2, point_t p3, color_t color, fill_t fillit)
+{
+    return triangle(p1.x,p1.y, p2.x,p2.y, p3.x,p3.y, color, 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)
@@ -1800,6 +1873,7 @@
 {
     RetCode_t ret = noerror;
 
+    INFO("triangle");
     PERFORMANCE_RESET;
     if (x1 == x2 && y1 == y2 && x1 == x3 && y1 == y3) {
         pixel(x1, y1);
@@ -1867,6 +1941,7 @@
 {
     RetCode_t ret = noerror;
 
+    INFO("circle");
     PERFORMANCE_RESET;
     if (radius <= 0 || (x - radius) < 0 || (x + radius) > screenwidth 
     || (y - radius) < 0 || (y + radius) > screenheight) {
@@ -1910,6 +1985,7 @@
 {
     RetCode_t ret = noerror;
 
+    INFO("ellipse");
     PERFORMANCE_RESET;
     if (radius1 <= 0 || radius2 <= 0 || (x - radius1) < 0 || (x + radius1) > screenwidth 
     || (y - radius2) < 0 || (y + radius2) > screenheight) {
@@ -2047,8 +2123,7 @@
 
 RetCode_t RA8875::SelectUserFont(const uint8_t * _font)
 {
-    INFO("Cursor(%d,%d)  %p", cursor_x, cursor_y, _font);
-    INFO("Text C(%d,%d)", GetTextCursor_X(), GetTextCursor_Y());
+    INFO("SelectUserFont(%p)", _font);
     if (_font) {
         HexDump("Font Memory", _font, 16);
         extFontHeight = _font[6];