BurstSPI support for improved performance

Fork of RA8875 by David Smart

Revision:
79:544eb4964795
Parent:
78:faf49c381591
Child:
80:cc4fab58179c
--- a/RA8875.cpp	Sun Dec 28 03:14:35 2014 +0000
+++ b/RA8875.cpp	Sun Dec 28 19:55:16 2014 +0000
@@ -70,13 +70,23 @@
 #define POLLWAITuSec 10
 
 // Private RawKeyMap for the Keyboard interface
-static const uint8_t KeyMap[22] = {
+static const uint8_t DefaultKeyMap[22] = {
     0,
     1,  2,  3,  4,  5,  6,  7,  8,  9, 10,
     11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
     255
 };
 
+static const char * ErrMessages[] = {
+    "noerror",                ///< no errors, command completed successfully
+    "bad_parameter",          ///< one or more parameters are invalid
+    "file_not_found",         ///< specified file could not be found
+    "not_bmp_format",         ///< file is not a .bmp file
+    "not_ico_format",         ///< file is not a .ico file
+    "not_supported_format",   ///< file format is not yet supported
+    "image_too_big",          ///< image is too large for the screen
+    "not_enough_ram",         ///< could not allocate ram for scanline
+};
 
 RA8875::RA8875(PinName mosi, PinName miso, PinName sclk, PinName csel, PinName reset, const char *name)
     : GraphicsDisplay(name)
@@ -84,29 +94,103 @@
     , cs(csel)
     , res(reset)
 {
-    font = NULL;                        // no external font, use internal.
-    select(false);                      // deselect the display
-    frequency(RA8875_DEFAULT_SPI_FREQ); // data rate
-    Reset();
-    Power(true);
-    Backlight_u8(255);
-    pKeyMap = KeyMap;
-#ifdef PERF_METRICS
-    performance.start();
-    ClearPerformance();
-#endif
 }
 
-
 //RA8875::~RA8875()
 //{
 //}
 
+RetCode_t RA8875::init(bool poweron, int width, int height, int color_bpp)
+{
+    INFO("init(%d,%d,%d,%d)", poweron, width, height, color_bpp);
+    font = NULL;                        // no external font, use internal.
+    pKeyMap = DefaultKeyMap;            // set default key map
+    _select(false);                      // deselect the display
+    frequency(RA8875_DEFAULT_SPI_FREQ); // data rate
+    Reset();
+    WriteCommand(0x88, 0x0B);                   // PLLC1 - Phase Lock Loop registers
+    wait_ms(1);
+    WriteCommand(0x89, 0x02);
+    wait_ms(1);
+
+    // System Config Register (SYSR)
+    if (color_bpp == 16) {
+        WriteCommand(0x10, 0x0C);               // 16-bpp (65K colors) color depth, 8-bit interface
+    } else { // color_bpp == 8
+        WriteCommand(0x10, 0x00);               // 8-bpp (256 colors)
+    }
+    // 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, 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, (height-1)&0xFF);        //VDHR0 //Vertical Display Height Bit [7:0]
+    WriteCommand(0x1a, (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]
+    WriteCommand(0x1e, 0x06);                   //VSTR1 //VSYNC Start Position[8]
+    WriteCommand(0x1f, 0x01);                   //VPWR //VSYNC Polarity ,VSYNC Pulse Width[6:0]
+
+    if (width >= 800 && height >= 480 && color_bpp > 8) {
+        WriteCommand(0x20, 0x00);               // DPCR - 1-layer mode when the resolution is too high
+    } else {
+        WriteCommand(0x20, 0x80);               // DPCR - 2-layer mode
+    }
+
+    // Set display image to Blue on Black as default
+    window(0,0, width, height);             // Initialize to full screen
+    SetTextCursorControl();
+    foreground(Blue);
+    background(Black);
+    cls(3);
+
+    Power(poweron);
+    if (poweron)
+        Backlight_u8(255);
+#ifdef PERF_METRICS
+    performance.start();
+    ClearPerformance();
+#endif
+    return noerror;
+}
+
+
+RetCode_t RA8875::Reset(void)
+{
+    RetCode_t ret;
+    
+    ret = WriteCommand(0x01, 0x01);   // Apply Display Off, Reset
+    wait_ms(2);                     // no idea if I need to wait, or how long
+    if (ret == noerror) {
+        ret = WriteCommand(0x01, 0x00);   // Display off, Remove reset
+        wait_ms(2);                     // no idea if I need to wait, or how long
+    }
+    return ret;
+}
+
+
+const char * RA8875::GetErrorMessage(RetCode_t code)
+{
+    if (code >= LastErrCode)
+        code = bad_parameter;
+    return ErrMessages[code];
+}
+
+
 uint16_t RA8875::GetDrawingLayer(void)
 {
     return (ReadCommand(0x41) & 0x01);
 }
 
+
 RetCode_t RA8875::SelectDrawingLayer(uint16_t layer)
 {
     unsigned char mwcr1 = ReadCommand(0x41) & ~0x01; // retain all but the currently selected layer
@@ -152,6 +236,7 @@
     return noerror;
 }
 
+
 color_t RA8875::GetBackgroundTransparencyColor(void)
 {
     RGBQUAD q;
@@ -186,20 +271,23 @@
     return WriteCommand(0xF0, value);   // INT
 }
 
+
 RetCode_t RA8875::SetKeyMap(const uint8_t * CodeList)
 {
     pKeyMap = CodeList;
     return noerror;
 }
 
+
 bool RA8875::readable(void)
 {
     return (ReadCommand(0xF1) & 0x10);  // check KS status - true if kbhit
 }
 
+
 uint8_t RA8875::getc(void)
 {
-    //#define GETC_DEV
+    //#define GETC_DEV      // for development
 #ifdef GETC_DEV
     uint8_t keyCode1, keyCode2;
 #endif
@@ -270,6 +358,7 @@
     return key;
 }
 
+
 #ifdef PERF_METRICS
 void RA8875::ClearPerformance()
 {
@@ -278,6 +367,7 @@
     idletime_usec = 0;
 }
 
+
 void RA8875::RegisterPerformance(method_e method)
 {
     unsigned long elapsed = performance.read_us();
@@ -286,11 +376,13 @@
         metrics[method] = elapsed;
 }
 
+
 void RA8875::CountIdleTime(uint32_t t)
 {
     idletime_usec += t;
 }
 
+
 void RA8875::ReportPerformance(Serial & pc)
 {
     pc.printf("\r\nPerformance Metrics\r\n");
@@ -310,13 +402,13 @@
 #else
     // This should be a little faster, but doesn't work...
     INFO("WriteCommandW(%02X, %04X)", command, data);
-    select(true);
-    spiwrite(0x80);
-    spiwrite(command);
-    //spiwrite(0x00);     // dummy
-    spiwrite(data & 0xFF);
-    spiwrite(data >> 8);
-    select(false);
+    _select(true);
+    _spiwrite(0x80);
+    _spiwrite(command);
+    //_spiwrite(0x00);     // dummy
+    _spiwrite(data & 0xFF);
+    _spiwrite(data >> 8);
+    _select(false);
 #endif
     return noerror;
 }
@@ -324,35 +416,35 @@
 
 RetCode_t RA8875::WriteCommand(unsigned char command, unsigned int data)
 {
-    select(true);
-    spiwrite(0x80);         // cmd: write command
-    spiwrite(command);
+    _select(true);
+    _spiwrite(0x80);         // cmd: write command
+    _spiwrite(command);
     if (data <= 0xFF) {   // only if in the valid range
-        spiwrite(0x00);
-        spiwrite(data);
+        _spiwrite(0x00);
+        _spiwrite(data);
     }
-    select(false);
+    _select(false);
     return noerror;
 }
 
 
 RetCode_t RA8875::WriteDataW(uint16_t data)
 {
-    select(true);
-    spiwrite(0x00);         // cmd: write data
-    spiwrite(data & 0xFF);
-    spiwrite(data >> 8);
-    select(false);
+    _select(true);
+    _spiwrite(0x00);         // cmd: write data
+    _spiwrite(data & 0xFF);
+    _spiwrite(data >> 8);
+    _select(false);
     return noerror;
 }
 
 
 RetCode_t RA8875::WriteData(unsigned char data)
 {
-    select(true);
-    spiwrite(0x00);
-    spiwrite(data);
-    select(false);
+    _select(true);
+    _spiwrite(0x00);
+    _spiwrite(data);
+    _select(false);
     return noerror;
 }
 
@@ -368,10 +460,10 @@
 {
     unsigned char data;
 
-    select(true);
-    spiwrite(0x40);
-    data = spiread();
-    select(false);
+    _select(true);
+    _spiwrite(0x40);
+    data = _spiread();
+    _select(false);
     return data;
 }
 
@@ -380,11 +472,11 @@
 {
     uint16_t data;
 
-    select(true);
-    spiwrite(0x40);
-    data  = spiread();
-    data |= (spiread() << 8);
-    select(false);
+    _select(true);
+    _spiwrite(0x40);
+    data  = _spiread();
+    data |= (_spiread() << 8);
+    _select(false);
     return data;
 }
 
@@ -393,13 +485,14 @@
 {
     unsigned char data;
 
-    select(true);
-    spiwrite(0xC0);         // These two bits are for the special "Status Read" [STSR]
-    data = spiread();
-    select(false);
+    _select(true);
+    _spiwrite(0xC0);         // These two bits are for the special "Status Read" [STSR]
+    data = _spiread();
+    _select(false);
     return data;
 }
 
+
 /// @todo add a timeout and return false, but how long
 /// to wait since some operations can be very long.
 bool RA8875::_WaitWhileBusy(uint8_t mask)
@@ -416,6 +509,7 @@
         return false;
 }
 
+
 /// @todo add a timeout and return false, but how long
 /// to wait since some operations can be very long.
 bool RA8875::_WaitWhileReg(uint8_t reg, uint8_t mask)
@@ -433,7 +527,6 @@
 }
 
 
-
 dim_t RA8875::fontwidth(void)
 {
     if (font == NULL)
@@ -670,10 +763,10 @@
             WriteCommandW(0x2C, y);
         } else {
             WriteCommand(0x02);                 // RA8875 Internal Fonts
-            select(true);
+            _select(true);
             WriteData(c);
             _WaitWhileBusy(0x80);
-            select(false);
+            _select(false);
         }
     }
     return c;
@@ -725,13 +818,13 @@
         }
 #else
         WriteCommand(0x02);
-        select(true);
+        _select(true);
         while (*string != '\0') {
             WriteData(*string);
             ++string;
             _WaitWhileBusy(0x80);
         }
-        select(false);
+        _select(false);
 #endif
     }
     if (font)
@@ -848,14 +941,14 @@
     WriteCommand(0x40,0x00);    // Graphics write mode
     SetGraphicsCursor(x, y);
     WriteCommand(0x02);
-    select(true);
-    spiwrite(0x00);         // Cmd: write data
+    _select(true);
+    _spiwrite(0x00);         // Cmd: write data
     while (count--) {
-        spiwrite(*p >> 8);
-        spiwrite(*p & 0xFF);
+        _spiwrite(*p >> 8);
+        _spiwrite(*p & 0xFF);
         p++;
     }
-    select(false);
+    _select(false);
     REGISTERPERFORMANCE(PRF_PIXELSTREAM);
     return(noerror);
 }
@@ -870,12 +963,12 @@
     WriteCommand(0x40,0x00);    // Graphics write mode
     SetGraphicsCursorRead(x, y);
     WriteCommand(0x02);
-    select(true);
-    spiwrite(0x40);         // Cmd: read data
-    spiwrite(0x00);         // dummy read
-    pixel  = spiread();
-    pixel |= (spiread() << 8);
-    select(false);
+    _select(true);
+    _spiwrite(0x40);         // Cmd: read data
+    _spiwrite(0x00);         // dummy read
+    pixel  = _spiread();
+    pixel |= (_spiread() << 8);
+    _select(false);
     REGISTERPERFORMANCE(PRF_READPIXEL);
     return pixel;
 }
@@ -890,15 +983,15 @@
     WriteCommand(0x40,0x00);    // Graphics write mode
     SetGraphicsCursorRead(x, y);
     WriteCommand(0x02);
-    select(true);
-    spiwrite(0x40);         // Cmd: read data
-    spiwrite(0x00);         // dummy read
+    _select(true);
+    _spiwrite(0x40);         // Cmd: read data
+    _spiwrite(0x00);         // dummy read
     while (count--) {
-        pixel  = spiread();
-        pixel |= (spiread() << 8);
+        pixel  = _spiread();
+        pixel |= (_spiread() << 8);
         *p++ = pixel;
     }
-    select(false);
+    _select(false);
     REGISTERPERFORMANCE(PRF_READPIXELSTREAM);
     return noerror;
 }
@@ -1188,17 +1281,6 @@
 }
 
 
-RetCode_t RA8875::Reset(void)
-{
-    WriteCommand(0x01, 0x01);   // Apply Display Off, Reset
-    wait_ms(2);                     // no idea if I need to wait, or how long
-    WriteCommand(0x01, 0x00);   // Display off, Remove reset
-    wait_ms(2);                     // no idea if I need to wait, or how long
-    init(RA8875_DISPLAY_WIDTH, RA8875_DISPLAY_HEIGHT, RA8875_COLORDEPTH_BPP);
-    return noerror;
-}
-
-
 RetCode_t RA8875::Backlight_u8(unsigned char brightness)
 {
     static bool is_enabled = false;
@@ -1327,7 +1409,7 @@
 ///////////////////////////////////////////////////////////////
 // Private functions
 
-unsigned char RA8875::spiwrite(unsigned char data)
+unsigned char RA8875::_spiwrite(unsigned char data)
 {
     unsigned char retval;
 
@@ -1338,7 +1420,7 @@
 }
 
 
-unsigned char RA8875::spiread(void)
+unsigned char RA8875::_spiread(void)
 {
     unsigned char retval;
     unsigned char data = 0;
@@ -1350,65 +1432,13 @@
 }
 
 
-RetCode_t RA8875::select(bool chipsel)
+RetCode_t RA8875::_select(bool chipsel)
 {
     cs = (chipsel == true) ? 0 : 1;
     return noerror;
 }
 
 
-RetCode_t RA8875::init(int width, int height, int color_bpp)
-{
-    Backlight_u8(0);
-    WriteCommand(0x88, 0x0B);                   // PLLC1 - Phase Lock Loop registers
-    wait_ms(1);
-    WriteCommand(0x89, 0x02);
-    wait_ms(1);
-
-    // System Config Register (SYSR)
-    if (color_bpp == 16) {
-        WriteCommand(0x10, 0x0C);               // 16-bpp (65K colors) color depth, 8-bit interface
-    } else { // color_bpp == 8
-        WriteCommand(0x10, 0x00);               // 8-bpp (256 colors)
-    }
-    // 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, 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, (height-1)&0xFF);        //VDHR0 //Vertical Display Height Bit [7:0]
-    WriteCommand(0x1a, (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]
-    WriteCommand(0x1e, 0x06);                   //VSTR1 //VSYNC Start Position[8]
-    WriteCommand(0x1f, 0x01);                   //VPWR //VSYNC Polarity ,VSYNC Pulse Width[6:0]
-
-    if (width >= 800 && height >= 480 && color_bpp > 8) {
-        WriteCommand(0x20, 0x00);               // DPCR - 1-layer mode when the resolution is too high
-    } else {
-        WriteCommand(0x20, 0x80);               // DPCR - 2-layer mode
-    }
-
-    // Set display image to Blue on Black as default
-    window(0,0, width, height);             // Initialize to full screen
-    SetTextCursorControl();
-    foreground(Blue);
-    background(Black);
-    SelectDrawingLayer(1);
-    cls();
-    SelectDrawingLayer(0);
-    cls();
-    return noerror;
-}
-
 RetCode_t RA8875::PrintScreen(uint16_t layer, loc_t x, loc_t y, dim_t w, dim_t h, const char *Name_BMP)
 {
 #if 1
@@ -1426,6 +1456,7 @@
 #endif
 }
 
+
 RetCode_t RA8875::PrintScreen(loc_t x, loc_t y, dim_t w, dim_t h, const char *Name_BMP)
 {
     BITMAPFILEHEADER BMP_Header;
@@ -2211,7 +2242,7 @@
             display.printf(" (%3d,%3d) => ", pTest[i].x, pTest[i].y);
             display.line(pTest[i].x-10, pTest[i].y, pTest[i].x+10, pTest[i].y, White);
             display.line(pTest[i].x, pTest[i].y-10, pTest[i].x, pTest[i].y+10, White);
-            while (!display.TouchPanelRead(&x, &y))
+            while (!display.TouchPanelA2DFiltered(&x, &y))
                 wait_ms(20);
             pSample[i].x = x;
             pSample[i].y = y;
@@ -2219,7 +2250,7 @@
             display.line(pTest[i].x, pTest[i].y-10, pTest[i].x, pTest[i].y+10, Black);
             display.foreground(Blue);
             display.printf(" (%4d,%4d)\r\n", x,y);
-            while (display.TouchPanelRead(&x, &y))
+            while (display.TouchPanelA2DFiltered(&x, &y))
                 wait_ms(20);
             wait(2);
         }
@@ -2244,7 +2275,7 @@
     t.start();
     do {
         point_t point = {0, 0};
-        if (display.TouchPanelPoint(&point)) {
+        if (display.TouchPanelReadable(&point)) {
             display.pixel(point.x, point.y, Red);
         }
     } while (t.read_ms() < 30000);
@@ -2415,4 +2446,4 @@
     }
 }
 
-#endif // TESTENABLE
\ No newline at end of file
+#endif // TESTENABLE