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 Feb 13 04:20:12 2019 +0000
Parent:
162:a2d7f1988711
Child:
164:76edd7d9cb68
Commit message:
Add ability to PrintScreen as an 8-bit bitmap, as an alternate to the default of 24-bit.

Changed in this revision

Bitmap.h 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
--- a/Bitmap.h	Mon Feb 11 03:44:42 2019 +0000
+++ b/Bitmap.h	Wed Feb 13 04:20:12 2019 +0000
@@ -31,7 +31,7 @@
     uint16_t    bfReserved1;      ///< reserved placeholder for the structure footprint
     uint16_t    bfReserved2;      ///< reserved placeholder for the structure footprint
     uint32_t    bfOffBits;        ///< Offset to bitmap data 
-    } BITMAPFILEHEADER;
+    } BITMAPFILEHEADER;           // Size: 14B
 
 /// Bitmap information header
 typedef struct                    /**** BMP file info structure ****/
@@ -47,7 +47,7 @@
     int32_t     biYPelsPerMeter;  ///< Y pixels per meter 
     uint32_t    biClrUsed;        ///< Number of colors used 
     uint32_t    biClrImportant;   ///< Number of important colors 
-    } BITMAPINFOHEADER;
+    } BITMAPINFOHEADER;           // Size: 40B
 #pragma pop
 
 #define BF_TYPE 0x4D42            /* "MB" */
--- a/RA8875.cpp	Mon Feb 11 03:44:42 2019 +0000
+++ b/RA8875.cpp	Wed Feb 13 04:20:12 2019 +0000
@@ -101,6 +101,75 @@
     "external abort",         ///< during an idle callback, the user code initiated an abort
 };
 
+typedef struct {
+    uint8_t b;
+    uint8_t g;
+    uint8_t r;
+    uint8_t a;
+} rgbTrio_t;
+
+static const rgbTrio_t WebColorPalette[] = {
+    {0x00,0x00,0x00,0xFF}, {0x00,0x00,0x33,0xFF}, {0x00,0x00,0x66,0xFF}, {0x00,0x00,0x99,0xFF}, {0x00,0x00,0xCC,0xFF}, {0x00,0x00,0xFF,0xFF},
+    {0x00,0x33,0x00,0xFF}, {0x00,0x33,0x33,0xFF}, {0x00,0x33,0x66,0xFF}, {0x00,0x33,0x99,0xFF}, {0x00,0x33,0xCC,0xFF}, {0x00,0x33,0xFF,0xFF},
+    {0x00,0x66,0x00,0xFF}, {0x00,0x66,0x33,0xFF}, {0x00,0x66,0x66,0xFF}, {0x00,0x66,0x99,0xFF}, {0x00,0x66,0xCC,0xFF}, {0x00,0x66,0xFF,0xFF},
+    {0x00,0x99,0x00,0xFF}, {0x00,0x99,0x33,0xFF}, {0x00,0x99,0x66,0xFF}, {0x00,0x99,0x99,0xFF}, {0x00,0x99,0xCC,0xFF}, {0x00,0x99,0xFF,0xFF},
+    {0x00,0xCC,0x00,0xFF}, {0x00,0xCC,0x33,0xFF}, {0x00,0xCC,0x66,0xFF}, {0x00,0xCC,0x99,0xFF}, {0x00,0xCC,0xCC,0xFF}, {0x00,0xCC,0xFF,0xFF},
+    {0x00,0xFF,0x00,0xFF}, {0x00,0xFF,0x33,0xFF}, {0x00,0xFF,0x66,0xFF}, {0x00,0xFF,0x99,0xFF}, {0x00,0xFF,0xCC,0xFF}, {0x00,0xFF,0xFF,0xFF},
+    {0x33,0x00,0x00,0xFF}, {0x33,0x00,0x33,0xFF}, {0x33,0x00,0x66,0xFF}, {0x33,0x00,0x99,0xFF}, {0x33,0x00,0xCC,0xFF}, {0x33,0x00,0xFF,0xFF},
+    {0x33,0x33,0x00,0xFF}, {0x33,0x33,0x33,0xFF}, {0x33,0x33,0x66,0xFF}, {0x33,0x33,0x99,0xFF}, {0x33,0x33,0xCC,0xFF}, {0x33,0x33,0xFF,0xFF},
+    {0x33,0x66,0x00,0xFF}, {0x33,0x66,0x33,0xFF}, {0x33,0x66,0x66,0xFF}, {0x33,0x66,0x99,0xFF}, {0x33,0x66,0xCC,0xFF}, {0x33,0x66,0xFF,0xFF},
+    {0x33,0x99,0x00,0xFF}, {0x33,0x99,0x33,0xFF}, {0x33,0x99,0x66,0xFF}, {0x33,0x99,0x99,0xFF}, {0x33,0x99,0xCC,0xFF}, {0x33,0x99,0xFF,0xFF},
+    {0x33,0xCC,0x00,0xFF}, {0x33,0xCC,0x33,0xFF}, {0x33,0xCC,0x66,0xFF}, {0x33,0xCC,0x99,0xFF}, {0x33,0xCC,0xCC,0xFF}, {0x33,0xCC,0xFF,0xFF},
+    {0x33,0xFF,0x00,0xFF}, {0x33,0xFF,0x33,0xFF}, {0x33,0xFF,0x66,0xFF}, {0x33,0xFF,0x99,0xFF}, {0x33,0xFF,0xCC,0xFF}, {0x33,0xFF,0xFF,0xFF},
+    {0x66,0x00,0x00,0xFF}, {0x66,0x00,0x33,0xFF}, {0x66,0x00,0x66,0xFF}, {0x66,0x00,0x99,0xFF}, {0x66,0x00,0xCC,0xFF}, {0x66,0x00,0xFF,0xFF},
+    {0x66,0x33,0x00,0xFF}, {0x66,0x33,0x33,0xFF}, {0x66,0x33,0x66,0xFF}, {0x66,0x33,0x99,0xFF}, {0x66,0x33,0xCC,0xFF}, {0x66,0x33,0xFF,0xFF},
+    {0x66,0x66,0x00,0xFF}, {0x66,0x66,0x33,0xFF}, {0x66,0x66,0x66,0xFF}, {0x66,0x66,0x99,0xFF}, {0x66,0x66,0xCC,0xFF}, {0x66,0x66,0xFF,0xFF},
+    {0x66,0x99,0x00,0xFF}, {0x66,0x99,0x33,0xFF}, {0x66,0x99,0x66,0xFF}, {0x66,0x99,0x99,0xFF}, {0x66,0x99,0xCC,0xFF}, {0x66,0x99,0xFF,0xFF},
+    {0x66,0xCC,0x00,0xFF}, {0x66,0xCC,0x33,0xFF}, {0x66,0xCC,0x66,0xFF}, {0x66,0xCC,0x99,0xFF}, {0x66,0xCC,0xCC,0xFF}, {0x66,0xCC,0xFF,0xFF},
+    {0x66,0xFF,0x00,0xFF}, {0x66,0xFF,0x33,0xFF}, {0x66,0xFF,0x66,0xFF}, {0x66,0xFF,0x99,0xFF}, {0x66,0xFF,0xCC,0xFF}, {0x66,0xFF,0xFF,0xFF},
+    {0x99,0x00,0x00,0xFF}, {0x99,0x00,0x33,0xFF}, {0x99,0x00,0x66,0xFF}, {0x99,0x00,0x99,0xFF}, {0x99,0x00,0xCC,0xFF}, {0x99,0x00,0xFF,0xFF},
+    {0x99,0x33,0x00,0xFF}, {0x99,0x33,0x33,0xFF}, {0x99,0x33,0x66,0xFF}, {0x99,0x33,0x99,0xFF}, {0x99,0x33,0xCC,0xFF}, {0x99,0x33,0xFF,0xFF},
+    {0x99,0x66,0x00,0xFF}, {0x99,0x66,0x33,0xFF}, {0x99,0x66,0x66,0xFF}, {0x99,0x66,0x99,0xFF}, {0x99,0x66,0xCC,0xFF}, {0x99,0x66,0xFF,0xFF},
+    {0x99,0x99,0x00,0xFF}, {0x99,0x99,0x33,0xFF}, {0x99,0x99,0x66,0xFF}, {0x99,0x99,0x99,0xFF}, {0x99,0x99,0xCC,0xFF}, {0x99,0x99,0xFF,0xFF},
+    {0x99,0xCC,0x00,0xFF}, {0x99,0xCC,0x33,0xFF}, {0x99,0xCC,0x66,0xFF}, {0x99,0xCC,0x99,0xFF}, {0x99,0xCC,0xCC,0xFF}, {0x99,0xCC,0xFF,0xFF},
+    {0x99,0xFF,0x00,0xFF}, {0x99,0xFF,0x33,0xFF}, {0x99,0xFF,0x66,0xFF}, {0x99,0xFF,0x99,0xFF}, {0x99,0xFF,0xCC,0xFF}, {0x99,0xFF,0xFF,0xFF},
+    {0xCC,0x00,0x00,0xFF}, {0xCC,0x00,0x33,0xFF}, {0xCC,0x00,0x66,0xFF}, {0xCC,0x00,0x99,0xFF}, {0xCC,0x00,0xCC,0xFF}, {0xCC,0x00,0xFF,0xFF},
+    {0xCC,0x33,0x00,0xFF}, {0xCC,0x33,0x33,0xFF}, {0xCC,0x33,0x66,0xFF}, {0xCC,0x33,0x99,0xFF}, {0xCC,0x33,0xCC,0xFF}, {0xCC,0x33,0xFF,0xFF},
+    {0xCC,0x66,0x00,0xFF}, {0xCC,0x66,0x33,0xFF}, {0xCC,0x66,0x66,0xFF}, {0xCC,0x66,0x99,0xFF}, {0xCC,0x66,0xCC,0xFF}, {0xCC,0x66,0xFF,0xFF},
+    {0xCC,0x99,0x00,0xFF}, {0xCC,0x99,0x33,0xFF}, {0xCC,0x99,0x66,0xFF}, {0xCC,0x99,0x99,0xFF}, {0xCC,0x99,0xCC,0xFF}, {0xCC,0x99,0xFF,0xFF},
+    {0xCC,0xCC,0x00,0xFF}, {0xCC,0xCC,0x33,0xFF}, {0xCC,0xCC,0x66,0xFF}, {0xCC,0xCC,0x99,0xFF}, {0xCC,0xCC,0xCC,0xFF}, {0xCC,0xCC,0xFF,0xFF},
+    {0xCC,0xFF,0x00,0xFF}, {0xCC,0xFF,0x33,0xFF}, {0xCC,0xFF,0x66,0xFF}, {0xCC,0xFF,0x99,0xFF}, {0xCC,0xFF,0xCC,0xFF}, {0xCC,0xFF,0xFF,0xFF},
+    {0xFF,0x00,0x00,0xFF}, {0xFF,0x00,0x33,0xFF}, {0xFF,0x00,0x66,0xFF}, {0xFF,0x00,0x99,0xFF}, {0xFF,0x00,0xCC,0xFF}, {0xFF,0x00,0xFF,0xFF},
+    {0xFF,0x33,0x00,0xFF}, {0xFF,0x33,0x33,0xFF}, {0xFF,0x33,0x66,0xFF}, {0xFF,0x33,0x99,0xFF}, {0xFF,0x33,0xCC,0xFF}, {0xFF,0x33,0xFF,0xFF},
+    {0xFF,0x66,0x00,0xFF}, {0xFF,0x66,0x33,0xFF}, {0xFF,0x66,0x66,0xFF}, {0xFF,0x66,0x99,0xFF}, {0xFF,0x66,0xCC,0xFF}, {0xFF,0x66,0xFF,0xFF},
+    {0xFF,0x99,0x00,0xFF}, {0xFF,0x99,0x33,0xFF}, {0xFF,0x99,0x66,0xFF}, {0xFF,0x99,0x99,0xFF}, {0xFF,0x99,0xCC,0xFF}, {0xFF,0x99,0xFF,0xFF},
+    {0xFF,0xCC,0x00,0xFF}, {0xFF,0xCC,0x33,0xFF}, {0xFF,0xCC,0x66,0xFF}, {0xFF,0xCC,0x99,0xFF}, {0xFF,0xCC,0xCC,0xFF}, {0xFF,0xCC,0xFF,0xFF},
+    {0xFF,0xFF,0x00,0xFF}, {0xFF,0xFF,0x33,0xFF}, {0xFF,0xFF,0x66,0xFF}, {0xFF,0xFF,0x99,0xFF}, {0xFF,0xFF,0xCC,0xFF}, {0xFF,0xFF,0xFF,0xFF},
+
+    {0x00,0x00,0x00,0xFF}, {0x00,0x00,0x00,0xFF}, {0x00,0x00,0x00,0xFF}, {0x00,0x00,0x00,0xFF}, {0x00,0x00,0x00,0xFF}, {0x00,0x00,0x00,0xFF}, 
+    {0x00,0x00,0x00,0xFF}, {0x00,0x00,0x00,0xFF}, {0x00,0x00,0x00,0xFF}, {0x00,0x00,0x00,0xFF}, {0x00,0x00,0x00,0xFF}, {0x00,0x00,0x00,0xFF}, 
+    {0x00,0x00,0x00,0xFF}, {0x00,0x00,0x00,0xFF}, {0x00,0x00,0x00,0xFF}, {0x00,0x00,0x00,0xFF}, {0x00,0x00,0x00,0xFF}, {0x00,0x00,0x00,0xFF}, 
+    {0x00,0x00,0x00,0xFF}, {0x00,0x00,0x00,0xFF}, {0x00,0x00,0x00,0xFF}, {0x00,0x00,0x00,0xFF}, {0x00,0x00,0x00,0xFF}, {0x00,0x00,0x00,0xFF}, 
+    {0x00,0x00,0x00,0xFF}, {0x00,0x00,0x00,0xFF}, {0x00,0x00,0x00,0xFF}, {0x00,0x00,0x00,0xFF}, {0x00,0x00,0x00,0xFF}, {0x00,0x00,0x00,0xFF}, 
+    {0x00,0x00,0x00,0xFF}, {0x00,0x00,0x00,0xFF}, {0x00,0x00,0x00,0xFF}, {0x00,0x00,0x00,0xFF}, {0x00,0x00,0x00,0xFF}, {0x00,0x00,0x00,0xFF}, 
+    {0x00,0x00,0x00,0xFF}, {0x00,0x00,0x00,0xFF}, {0x00,0x00,0x00,0xFF}, {0x00,0x00,0x00,0xFF}, 
+};
+
+#define sqr(a) (double)((a) * (a))
+
+static int FindNearestWebColor(uint8_t r, uint8_t g, uint8_t b) {
+    int bestNdx = 0;
+    float bestDiff = sqrt(sqr(r - WebColorPalette[0].r) + sqr(g - WebColorPalette[0].g) + sqr(b - WebColorPalette[0].b));
+    for (int i=1; i<216; i++) {
+        float thisDiff = sqrt(sqr(r - WebColorPalette[i].r) + sqr(g - WebColorPalette[i].g) + sqr(b - WebColorPalette[i].b));
+        if (thisDiff < bestDiff) {
+            bestDiff = thisDiff;
+            bestNdx = i;
+        }
+    }
+    return bestNdx;
+}
+
 RA8875::RA8875(PinName mosi, PinName miso, PinName sclk, PinName csel, PinName reset, 
     const char *name)
     : GraphicsDisplay(name)
@@ -2241,7 +2310,8 @@
     }
 }
 
-RetCode_t RA8875::PrintScreen(loc_t x, loc_t y, dim_t w, dim_t h, const char *Name_BMP)
+
+RetCode_t RA8875::PrintScreen(loc_t x, loc_t y, dim_t w, dim_t h, const char *Name_BMP, uint8_t bitsPerPixel)
 {
     BITMAPFILEHEADER BMP_Header;
     BITMAPINFOHEADER BMP_Info;
@@ -2249,33 +2319,49 @@
     color_t * pixelBuffer = NULL;
     color_t * pixelBuffer2 = NULL;
     
-    INFO("(%d,%d) - (%d,%d) %s", x,y,w,h,Name_BMP);
+    INFO("(%d,%d)-(%d,%d)x%d %s", x,y,w,h,bitsPerPixel,Name_BMP);
     if (x >= 0 && x < screenwidth
             && y >= 0 && y < screenheight
             && w > 0 && x + w <= screenwidth
             && h > 0 && y + h <= screenheight) {
-
         BMP_Header.bfType = BF_TYPE;
-        BMP_Header.bfSize = (w * h * sizeof(RGBQUAD)) + sizeof(BMP_Header) + sizeof(BMP_Info);
         BMP_Header.bfReserved1 = 0;
         BMP_Header.bfReserved2 = 0;
-        BMP_Header.bfOffBits = sizeof(BMP_Header) + sizeof(BMP_Info);
+        switch (bitsPerPixel) {
+            case 24:
+                BMP_Header.bfOffBits = sizeof(BMP_Header) + sizeof(BMP_Info);
+                BMP_Header.bfSize = (h * RoundUp(w * sizeof(RGBQUAD),4)) + BMP_Header.bfOffBits;
+                break;
+            case 8:
+            default:
+                BMP_Header.bfOffBits = sizeof(BMP_Header) + sizeof(BMP_Info) + sizeof(WebColorPalette);
+                INFO("Initial Offset to Bitstream %X", BMP_Header.bfOffBits);
+                //if (BMP_Header.bfOffBits & 0x03) {
+                //    BMP_Header.bfOffBits += (4 - (BMP_Header.bfOffBits & 0x03));
+                //}
+                BMP_Header.bfSize = (h * RoundUp(w * 1,4)) + BMP_Header.bfOffBits;
+                break;
+        }
+        INFO("Offset to Bitstream %X", BMP_Header.bfOffBits);
 
         // Bytes in the line buffer
-        int lineBufSize = RoundUp(3 * w, 4);    // ((24 * w + 7)/8);
+        int lineBufSize = RoundUp(((bitsPerPixel == 24) ? 3 : 1) * w, 4);
         INFO("LineBufSize: %d", lineBufSize);
 
         BMP_Info.biSize = sizeof(BMP_Info);
         BMP_Info.biWidth = w;
         BMP_Info.biHeight = h;
         BMP_Info.biPlanes = 1;
-        BMP_Info.biBitCount = 24;
+        BMP_Info.biBitCount = bitsPerPixel;
         BMP_Info.biCompression = BI_RGB;
         BMP_Info.biSizeImage = lineBufSize * h;
         BMP_Info.biXPelsPerMeter = 0;
         BMP_Info.biYPelsPerMeter = 0;
-        BMP_Info.biClrUsed = 0;
-        BMP_Info.biClrImportant = 0;
+        // for 24-bit, there is no palette, so these are zero
+        // for 8-bit, there can be up to 256 RGB values in the palette
+        
+        BMP_Info.biClrUsed = (bitsPerPixel == 24) ? 0 : sizeof(WebColorPalette)/sizeof(WebColorPalette[0]);    // for 8b/pixel
+        BMP_Info.biClrImportant = BMP_Info.biClrUsed;
 
         // Allocate the memory we need to proceed
         lineBuffer = (uint8_t *)swMalloc(lineBufSize);
@@ -2329,7 +2415,16 @@
 
         HexDump("BMP_Info", (uint8_t *)&BMP_Info, sizeof(BMP_Info));
         fwrite(&BMP_Info, sizeof(char), sizeof(BMP_Info), Image);
-
+        
+        if (bitsPerPixel != 24) {
+            HexDump("Palette", (uint8_t *)&WebColorPalette, sizeof(WebColorPalette));
+            fwrite(&WebColorPalette, sizeof(char), sizeof(WebColorPalette), Image);
+            if (0 && sizeof(WebColorPalette) % 4) {
+                const uint8_t padd[] = { 0, 0, 0 };
+                fwrite(&padd, sizeof(char), 
+                    (sizeof(BMP_Header) + sizeof(BMP_Info) + sizeof(WebColorPalette)) % 4, Image);
+            }
+        }
         //color_t transparency = GetBackgroundTransparencyColor();
         LayerMode_T ltpr0 = GetLayerMode();
 
@@ -2366,7 +2461,7 @@
                 }
             }
             INFO("Line: %3d", j);
-            HexDump("Raster", (uint8_t *)pixelBuffer, w * sizeof(color_t));
+            //HexDump("Raster", (uint8_t *)pixelBuffer, w * sizeof(color_t));
             // Convert the local buffer to RGBQUAD format
             int lb = 0;
             for (int i=0; i<w; i++) {
@@ -2382,25 +2477,36 @@
                     case 2: // lighten-overlay  (@TODO Not supported yet)
                     case 6: // Floating Windows     (@TODO not sure how to support)
                     default: // Reserved...
+                        //lineBuffer[lb++] = q0.rgbBlue;
+                        //lineBuffer[lb++] = q0.rgbGreen;
+                        //lineBuffer[lb++] = q0.rgbRed;
+                        break;
+                    case 3: // transparent mode (@TODO Read the background color register for transparent)
+                    case 4: // boolean or
+                        q0.rgbBlue = q0.rgbBlue | q1.rgbBlue;
+                        q0.rgbGreen = q0.rgbGreen | q1.rgbGreen;
+                        q0.rgbRed = q0.rgbRed | q1.rgbRed;
+                        break;
+                    case 5: // boolean AND
+                        q0.rgbBlue = q0.rgbBlue & q1.rgbBlue;
+                        q0.rgbGreen = q0.rgbGreen & q1.rgbGreen;
+                        q0.rgbRed = q0.rgbRed & q1.rgbRed;
+                        break;
+                }
+                switch (bitsPerPixel) {
+                    case 24:
                         lineBuffer[lb++] = q0.rgbBlue;
                         lineBuffer[lb++] = q0.rgbGreen;
                         lineBuffer[lb++] = q0.rgbRed;
                         break;
-                    case 3: // transparent mode (@TODO Read the background color register for transparent)
-                    case 4: // boolean or
-                        lineBuffer[lb++] = q0.rgbBlue | q1.rgbBlue;
-                        lineBuffer[lb++] = q0.rgbGreen | q1.rgbGreen;
-                        lineBuffer[lb++] = q0.rgbRed | q1.rgbRed;
-                        break;
-                    case 5: // boolean AND
-                        lineBuffer[lb++] = q0.rgbBlue & q1.rgbBlue;
-                        lineBuffer[lb++] = q0.rgbGreen & q1.rgbGreen;
-                        lineBuffer[lb++] = q0.rgbRed & q1.rgbRed;
+                    case 8:
+                    default:
+                        lineBuffer[lb++] = FindNearestWebColor(q0.rgbRed,q0.rgbGreen,q0.rgbBlue);
                         break;
                 }
             }
             //if (j == h - 1) {
-                HexDump("Line", lineBuffer, lineBufSize);
+            //    HexDump("Line", lineBuffer, lineBufSize);
             //}
             // Write to disk
             fwrite(lineBuffer, sizeof(char), lineBufSize, Image);
--- a/RA8875.h	Mon Feb 11 03:44:42 2019 +0000
+++ b/RA8875.h	Wed Feb 13 04:20:12 2019 +0000
@@ -2674,10 +2674,12 @@
     /// @param[in] y is the top edge of the region to capture
     /// @param[in] w is the width of the region to capture
     /// @param[in] h is the height of the region to capture.
-    /// @param[out] Name_BMP is the filename to write the image to.
+    /// @param[in] Name_BMP is the filename to write the image to.
+    /// @param[in] bitsPerPixel is optional, defaults to 24, and only 
+    ///             accepts the values 24, 8
     /// @return success or error code.
     ///
-    RetCode_t PrintScreen(loc_t x, loc_t y, dim_t w, dim_t h, const char *Name_BMP);
+    RetCode_t PrintScreen(loc_t x, loc_t y, dim_t w, dim_t h, const char *Name_BMP, uint8_t bitsPerPixel = 24);
 
     
     /// This method captures the specified area as a 24-bit bitmap file