LCD LIB

Dependents:   HagridOS5

Fork of RA8875 by David Smart

Files at this revision

API Documentation at this revision

Comitter:
WiredHome
Date:
Sat Feb 27 18:40:35 2016 +0000
Parent:
104:8d1d3832a215
Child:
106:c80828f5dea4
Commit message:
Improved 8-bit color support, which permits dual-layer at higher resolutions.

Changed in this revision

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/RA8875.cpp	Mon Feb 08 01:47:56 2016 +0000
+++ b/RA8875.cpp	Sat Feb 27 18:40:35 2016 +0000
@@ -119,6 +119,7 @@
     wait_ms(1);
 
     // System Config Register (SYSR)
+    screenbpp = color_bpp;
     if (color_bpp == 16) {
         WriteCommand(0x10, 0x0C);               // 16-bpp (65K colors) color depth, 8-bit interface
     } else { // color_bpp == 8
@@ -215,7 +216,7 @@
 {
     unsigned char mwcr1 = ReadCommand(0x41) & ~0x01; // retain all but the currently selected layer
 
-    if (width() >= 800 && height() >= 480 && color_bpp() == 8) {
+    if (screenwidth >= 800 && screenheight >= 480 && screenbpp == 8) {
         return bad_parameter;
     } else if (layer > 1) {
         return bad_parameter;
@@ -234,6 +235,7 @@
 RetCode_t RA8875::SetLayerMode(LayerMode_T mode)
 {
     unsigned char ltpr0 = ReadCommand(0x52) & ~0x7; // retain all but the display layer mode
+    
     if (mode <= (LayerMode_T)6) {
         WriteCommand(0x52, ltpr0 | (mode & 0x7));
         return noerror;
@@ -266,6 +268,7 @@
 color_t RA8875::GetBackgroundTransparencyColor(void)
 {
     RGBQUAD q;
+    
     q.rgbRed = ReadCommand(0x67);
     q.rgbGreen = ReadCommand(0x68);
     q.rgbBlue = ReadCommand(0x69);
@@ -565,6 +568,24 @@
         return false;
 }
 
+uint8_t RA8875::_cvt16to8(color_t c16)
+{
+    return ((c16 >> 8) & 0xE0)
+        | ((c16 >> 6) & 0x1C)
+        | ((c16 >> 3) & 0x03);
+}
+
+color_t RA8875::_cvt8to16(uint8_t c8)
+{
+    color_t c16 = ((c8 & 0xE0) << 8)
+        | ((c8 & 0xC0) << 5)
+        | ((c8 & 0x1C) << 6)
+        | ((c8 & 0x1C) << 3)
+        | ((c8 & 0x03) << 3)
+        | ((c8 & 0x03) << 1)
+        | ((c8 & 0x03) >> 1);
+    return c16;
+}
 
 dim_t RA8875::fontwidth(void)
 {
@@ -592,13 +613,13 @@
 
 int RA8875::columns(void)
 {
-    return width() / fontwidth();
+    return screenwidth / fontwidth();
 }
 
 
 int RA8875::rows(void)
 {
-    return height() / fontheight();
+    return screenheight / fontheight();
 }
 
 
@@ -622,10 +643,7 @@
 
 dim_t RA8875::color_bpp(void)
 {
-    if ((ReadCommand(0x10) & 0x0C) == 0x04)
-        return 16;
-    else
-        return 8;
+    return screenbpp;
 }
 
 RetCode_t RA8875::SetTextCursor(point_t p)
@@ -838,11 +856,11 @@
             INFO("(%d,%d) ,charWidth: %d '%c", cursor_x, cursor_y, charWidth, c);
             if (charRecord) {
                 //cursor_x += advance;
-                if (cursor_x + charWidth >= width()) {
+                if (cursor_x + charWidth >= screenwidth) {
                     cursor_x = 0;
                     cursor_y += charHeight;
                 }
-                if (cursor_y + charHeight >= height()) {
+                if (cursor_y + charHeight >= screenheight) {
                     cursor_y = 0;               // @todo Should it scroll?
                 }
                 (void)character(cursor_x, cursor_y, c);
@@ -1020,12 +1038,7 @@
     RetCode_t ret;
 
     PERFORMANCE_RESET;
-#if 1
     ret = pixelStream(&color, 1, x,y);
-#else
-    foreground(color);
-    ret = pixel(x,y);
-#endif
     REGISTERPERFORMANCE(PRF_DRAWPIXEL);
     return ret;
 }
@@ -1037,15 +1050,7 @@
 
     PERFORMANCE_RESET;
     color_t color = GetForeColor();
-#if 1
     ret = pixelStream(&color, 1, x, y);
-#else
-    WriteCommand(0x40,0x00);    // Graphics write mode
-    SetGraphicsCursor(x, y);
-    WriteCommand(0x02);
-    WriteDataW(color);
-    ret = noerror;
-#endif
     REGISTERPERFORMANCE(PRF_DRAWPIXEL);
     return ret;
 }
@@ -1060,8 +1065,12 @@
     _select(true);
     _spiwrite(0x00);         // Cmd: write data
     while (count--) {
-        _spiwrite(*p >> 8);
-        _spiwrite(*p & 0xFF);
+        if (screenbpp == 16) {
+            _spiwrite(*p >> 8);
+            _spiwrite(*p & 0xFF);
+        } else {
+            _spiwrite(_cvt16to8(*p));
+        }
         p++;
     }
     _select(false);
@@ -1082,8 +1091,12 @@
     _select(true);
     _spiwrite(0x40);         // Cmd: read data
     _spiwrite(0x00);         // dummy read
-    pixel  = _spiread();
-    pixel |= (_spiread() << 8);
+    if (screenbpp == 16) {
+        pixel  = _spiread();
+        pixel |= (_spiread() << 8);
+    } else {
+        pixel = _cvt8to16(_spiread());
+    }
     _select(false);
     REGISTERPERFORMANCE(PRF_READPIXEL);
     return pixel;
@@ -1095,22 +1108,21 @@
     color_t pixel;
     RetCode_t ret = noerror;
 
-    //INFO("getPixelStream(%p, %u, %d, %d)", p, count, x, y);
     PERFORMANCE_RESET;
-    //WriteCommand(0x45,0x00);    // read left->right, top->bottom
     ret = WriteCommand(0x40,0x00);    // Graphics write mode
-    //INFO("  r = %d", ret);
     ret = SetGraphicsCursorRead(x, y);
-    //INFO("  r = %d", ret);
     ret = WriteCommand(0x02);
-    //INFO("  r = %d", ret);
     _select(true);
     _spiwrite(0x40);         // Cmd: read data
     _spiwrite(0x00);         // dummy read
     _spiwrite(0x00);         // dummy read  [20150201: Required to properly align the data stream. Not yet sure why...]
     while (count--) {
-        pixel  = _spiread();
-        pixel |= (_spiread() << 8);
+        if (screenbpp == 16) {
+            pixel  = _spiread();
+            pixel |= (_spiread() << 8);
+        } else {
+            pixel = _cvt8to16(_spiread());
+        }
         *p++ = pixel;
     }
     _select(false);
@@ -1187,8 +1199,8 @@
     RetCode_t ret = noerror;
     PERFORMANCE_RESET;
     // check for bad_parameter
-    if (x1 < 0 || x1 >= width() || x2 < 0 || x2 >= width() 
-    || y1 < 0 || y1 >= height() || y2 < 0 || y2 >= height()) {
+    if (x1 < 0 || x1 >= screenwidth || x2 < 0 || x2 >= screenwidth 
+    || y1 < 0 || y1 >= screenheight || y2 < 0 || y2 >= screenheight) {
         ret = bad_parameter;
     } else {
         if (x1 == x2 && y1 == y2) {
@@ -1237,8 +1249,8 @@
     RetCode_t ret = noerror;
 
     PERFORMANCE_RESET;
-    if (x1 < 0 || x1 >= width() || x2 < 0 || x2 >= width() 
-    || y1 < 0 || y1 >= height() || y2 < 0 || y2 >= height()) {
+    if (x1 < 0 || x1 >= screenwidth || x2 < 0 || x2 >= screenwidth 
+    || y1 < 0 || y1 >= screenheight || y2 < 0 || y2 >= screenheight) {
         ret = bad_parameter;
     } else if (x1 > x2 || y1 > y2 || (radius1 > (x2-x1)/2) || (radius2 > (y2-y1)/2) ) {
         ret = bad_parameter;
@@ -1275,8 +1287,8 @@
 {
     RetCode_t ret;
 
-    if (x1 < 0 || x1 >= width() || x2 < 0 || x2 >= width() || x3 < 0 || x3 >= width()
-    || y1 < 0 || y1 >= height() || y2 < 0 || y2 >= height() || y3 < 0 || y3 >= height())
+    if (x1 < 0 || x1 >= screenwidth || x2 < 0 || x2 >= screenwidth || x3 < 0 || x3 >= screenwidth
+    || y1 < 0 || y1 >= screenheight || y2 < 0 || y2 >= screenheight || y3 < 0 || y3 >= screenheight)
         ret = bad_parameter;
     foreground(color);
     ret = triangle(x1,y1,x2,y2,x3,y3,fillit);
@@ -1365,8 +1377,8 @@
     RetCode_t ret = noerror;
 
     PERFORMANCE_RESET;
-    if (radius <= 0 || (x - radius) < 0 || (x + radius) > width() 
-    || (y - radius) < 0 || (y + radius) > height()) {
+    if (radius <= 0 || (x - radius) < 0 || (x + radius) > screenwidth 
+    || (y - radius) < 0 || (y + radius) > screenheight) {
         ret = bad_parameter;
     } else if (radius == 1) {
         pixel(x,y);
@@ -1405,8 +1417,8 @@
     RetCode_t ret = noerror;
 
     PERFORMANCE_RESET;
-    if (radius1 <= 0 || radius2 <= 0 || (x - radius1) < 0 || (x + radius1) > width() 
-    || (y - radius2) < 0 || (y + radius2) > height()) {
+    if (radius1 <= 0 || radius2 <= 0 || (x - radius1) < 0 || (x + radius1) > screenwidth 
+    || (y - radius2) < 0 || (y + radius2) > screenheight) {
         ret = bad_parameter;
     } else if (radius1 == 1 && radius2 == 1) {
         pixel(x, y);
@@ -1680,10 +1692,10 @@
     color_t * pixelBuffer2 = NULL;
     
     INFO("(%d,%d) - (%d,%d)", x,y,w,h);
-    if (x >= 0 && x < width()
-            && y >= 0 && y < height()
-            && w > 0 && x + w <= width()
-            && h > 0 && y + h <= height()) {
+    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_Header);
@@ -1843,10 +1855,10 @@
     color_t * pixelBuffer2 = NULL;
     
     INFO("(%d,%d) - (%d,%d) %s", x,y,w,h,Name_BMP);
-    if (x >= 0 && x < width()
-            && y >= 0 && y < height()
-            && w > 0 && x + w <= width()
-            && h > 0 && y + h <= height()) {
+    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_Header);
@@ -2854,3 +2866,4 @@
 }
 
 #endif // TESTENABLE
+
--- a/RA8875.h	Mon Feb 08 01:47:56 2016 +0000
+++ b/RA8875.h	Sat Feb 27 18:40:35 2016 +0000
@@ -2039,6 +2039,20 @@
     ///
     int _external_getCharWidth(int c);
     
+    /// Convert a 16-bit color value to an 8-bit value
+    ///
+    /// @param[in] c16 is the 16-bit color value to convert.
+    /// @returns 8-bit color value.
+    ///
+    uint8_t _cvt16to8(color_t c16);
+
+    /// Convert an 8-bit color value to a 16-bit value
+    ///
+    /// @param[in] c8 is the 8-bit color value to convert.
+    /// @returns 16-bit color value.
+    ///
+    color_t _cvt8to16(uint8_t c8);
+    
     /// Select the peripheral to use it.
     ///
     /// @param[in] chipsel when true will select the peripheral, and when false
@@ -2103,6 +2117,8 @@
     DigitalOut cs;                  ///< chip select pin, assumed active low
     DigitalOut res;                 ///< reset pin, assumed active low
     
+    // display metrics to avoid lengthy spi read queries
+    uint8_t screenbpp;              ///< configured bits per pixel
     dim_t screenwidth;              ///< configured screen width
     dim_t screenheight;             ///< configured screen height
     bool portraitmode;              ///< set true when in portrait mode (w,h are reversed)