Demo of RA8875 TFT touch display on Freescale FRDM-K64F Forked from David Smart https://developer.mbed.org/users/WiredHome/

Dependencies:   RA8875 menu SDFileSystem mbed

Fork of PUB_RA8875_mPaint by David Smart

Revision:
1:0fdc10700ed2
Parent:
0:326a3f29e21b
Child:
2:cf295dad3192
--- a/main.cpp	Thu Jan 01 21:54:21 2015 +0000
+++ b/main.cpp	Fri Jan 02 23:19:26 2015 +0000
@@ -1,8 +1,20 @@
-//
+/// mPaint is a simple drawing program, used to explore the touch
+/// APIs of the RA8875 display library.
+///
+/// @note Copyright © 2015 by Smartware Computing, all rights reserved.
+///     Individuals may use this application for evaluation or non-commercial
+///     purposes. Within this restriction, changes may be made to this application
+///     as long as this copyright notice is retained. The user shall make
+///     clear that their work is a derived work, and not the original.
+///     Users of this application and sources accept this application "as is" and
+///     shall hold harmless Smartware Computing, for any undesired results while
+///     using this application - whether real or imagined.
+///
+/// @author David Smart, Smartware Computing
 //
 // +----------------------------------------------------+
 // | File Edit Pen Tools  [sample](o)[rrrr][gggg][bbbb] |
-// +----------------------------------------------------+
+// +----------------------------------------------------+ 16
 // |                                                    |
 // |      canvas                                        |
 // |                                                    |
@@ -15,16 +27,31 @@
 // |                                                    |
 // +----------------------------------------------------+
 // | (xxx,yyy) - (xxx,yyy)               rgb (RR,GG,BB) |
-// +----------------------------------------------------+
-//
+// +----------------------------------------------------+ 271
+// 0                                                  479
 //
 #include "mbed.h"           // tested with v92
 #include "RA8875.h"         // tested with v80
 #include "menu.h"
 
+//#define DEBUG "mPaint"
+// ...
+// INFO("Stuff to show %d", var); // new-line is automatically appended
+//
+#if (defined(DEBUG) && !defined(TARGET_LPC11U24))
+#define INFO(x, ...) std::printf("[INF %s %3d] "x"\r\n", DEBUG, __LINE__, ##__VA_ARGS__);
+#define WARN(x, ...) std::printf("[WRN %s %3d] "x"\r\n", DEBUG, __LINE__, ##__VA_ARGS__);
+#define ERR(x, ...)  std::printf("[ERR %s %3d] "x"\r\n", DEBUG, __LINE__, ##__VA_ARGS__);
+#else
+#define INFO(x, ...)
+#define WARN(x, ...)
+#define ERR(x, ...)
+#define HexDump(a, b, c)
+#endif
+
 // Local File System:
 // - Store the touch screen calibration
-// - Capture image in BMP format.
+// - Capture works of art in BMP format.
 LocalFileSystem local("local");
 
 // The display interface
@@ -33,18 +60,21 @@
 // A monitor port for the SW developer.
 Serial pc(USBTX, USBRX);
 
+// list of tools (dots, lines, joined lines).
 typedef enum {
-    dot,
-    line
+    dot,                            // draw dots at the point
+    line,                           // connected line from touch(point) to release(point)
+    join                            // connected lines while held(point)
 } tooltype_t;                       // what tool are we using to draw
 
-color_t rgb = Black;                // the composite color value
-uint8_t rgbVal[3] = { 0, 0, 0 };    // host each of the individual values
-uint32_t pensize = 1;               // pensize is user selectable
-tooltype_t selectedtooltype = dot;  // 0:dot, 1:line
+color_t rgb = Black;                // the composite color value to draw in.
+uint8_t rgbVal[3] = { 0, 0, 0 };    // hosts each of the individual values
+uint32_t pensize = 1;               // pensize is user selectable within a small range.
+tooltype_t selectedtooltype = dot;  // 0:dot, 1:line, 2:join
 point_t origin = { 0, 0};           // tracks origin when drawing a line
 
 
+// Adjust the following if using the 800x600 display
 const rect_t RGBList[] = {          // regions on the display for special tools
     { 309,0, 359,15 },    // R
     { 369,0, 419,15 },    // G
@@ -103,8 +133,9 @@
 };
 
 Menu::menu_item_t tools_menu[] = {
-    { "point", NULL, NULL, Tools_Type, 0, NULL },
-    { "line",  NULL, NULL, Tools_Type, 1, NULL },
+    { "point", NULL, NULL, Tools_Type, dot, NULL },
+    { "line",  NULL, NULL, Tools_Type, line, NULL },
+    { "join",  NULL, NULL, Tools_Type, join, NULL },
     { NULL, NULL, NULL, NULL, 0, NULL },
 };
 
@@ -119,18 +150,18 @@
 
 Menu::post_fnc_action_t File(uint32_t v)
 {
-    printf("File\r\n");
+    INFO("File");
     return Menu::no_action;
 }
 Menu::post_fnc_action_t File_New(uint32_t v)
 {
-    printf("File_New\r\n");
+    INFO("File_New");
     InitDisplay();
     return Menu::no_action;
 }
 Menu::post_fnc_action_t File_Save(uint32_t v)
 {
-    printf("File_Save\r\n");
+    INFO("File_Save");
     RA8875::LayerMode_T l = lcd.GetLayerMode();
     lcd.SetLayerMode(RA8875::ShowLayer0);
     GetScreenCapture();
@@ -139,31 +170,31 @@
 }
 Menu::post_fnc_action_t File_Save_All(uint32_t v)
 {
-    printf("File_Save_All\r\n");
+    INFO("File_Save_All");
     GetScreenCapture();
     return Menu::close_menu;
 }
 Menu::post_fnc_action_t File_Cal(uint32_t v)
 {
-    printf("Tools_Cal\r\n");
+    INFO("Tools_Cal");
     CalibrateTS();
     return Menu::no_action;
 }
 Menu::post_fnc_action_t File_Reset(uint32_t v)
 {
-    printf("rebooting now...\r\n");
+    INFO("rebooting now...");
     wait_ms(1000);
     mbed_reset();
     return Menu::no_action;
 }
 Menu::post_fnc_action_t Edit(uint32_t v)
 {
-    printf("Edit\r\n");
+    INFO("Edit");
     return Menu::no_action;
 }
 Menu::post_fnc_action_t Tools(uint32_t v)
 {
-    printf("Tools\r\n");
+    INFO("Tools");
     return Menu::no_action;
 }
 Menu::post_fnc_action_t PenSize(uint32_t v)
@@ -173,15 +204,16 @@
         pensize = 1;
     else if (pensize > 8)
         pensize = 8;
-    pc.printf("PenSize(%d)\r\n", pensize);
+    INFO("PenSize(%d)", pensize);
     ShowSampleRGB();
     return Menu::close_menu;
 }
 Menu::post_fnc_action_t Tools_Type(uint32_t v)
 {
     switch (v) {
-        case 0: // dot
-        case 1: // line
+        case dot:
+        case line:
+        case join:
             selectedtooltype = (tooltype_t)v;
             break;
         default:
@@ -193,12 +225,14 @@
 
 void ShowSampleRGB(void)
 {
+    loc_t middle = (RGBList[3].p1.y + RGBList[3].p2.y)/2;
     lcd.fillrect(RGBList[3], Black);
     lcd.fillrect(RGBList[3], rgb);
-    if (selectedtooltype == 0) {
-        lcd.fillcircle(275,8, pensize, rgb);
+    if (selectedtooltype == dot) {
+        lcd.fillcircle((RGBList[3].p1.x + RGBList[3].p2.x)/2,
+            middle, pensize, rgb);
     } else {
-        lcd.fillrect(270,8-pensize/2, 280,8+pensize/2, rgb);
+        lcd.fillrect(RGBList[3].p1.x,middle-pensize/2, RGBList[3].p2.x,middle+pensize/2, rgb);
     }
 }
 
@@ -209,18 +243,18 @@
     RetCode_t r;
 
     r = lcd.TouchPanelCalibrate("Calibrate the touch panel", &matrix);
-    pc.printf("  ret: %d\r\n", r);
+    INFO("  ret: %d", r);
     if (r == noerror) {
         fh = fopen("/local/tpcal.cfg", "wb");
         if (fh) {
             fwrite(&matrix, sizeof(tpMatrix_t), 1, fh);
             fclose(fh);
-            pc.printf("  tp cal written.\r\n");
+            INFO("  tp cal written.");
         } else {
-            pc.printf("  couldn't open tpcal file.\r\n");
+            WARN("  couldn't open tpcal file.");
         }
     } else {
-        pc.printf("error return: %d\r\n", r);
+        ERR("error return: %d", r);
     }
 }
 
@@ -235,7 +269,7 @@
         fread(&matrix, sizeof(tpMatrix_t), 1, fh);
         fclose(fh);
         lcd.TouchPanelSetMatrix(&matrix);
-        pc.printf("  tp cal loaded.\r\n");
+        INFO("  tp cal loaded.");
     } else {
         CalibrateTS();
     }
@@ -258,13 +292,13 @@
     char fqfn[50];
     int i = 0;
 
-    pc.printf("Screen Capture... ");
+    INFO("Screen Capture... ");
     for (i=1; i< 100; i++) {
         snprintf(fqfn, sizeof(fqfn), "/local/Screen%02d.bmp", i);
         FILE * fh = fopen(fqfn, "rb");
         if (!fh) {
-            lcd.PrintScreen(0,0,480,272,fqfn);
-            pc.printf(" as /local/Screen%02d.bmp\r\n", i);
+            lcd.PrintScreen(0,0,lcd.width(),lcd.height(),fqfn);
+            INFO(" as /local/Screen%02d.bmp", i);
             return i;
         } else {
             fclose(fh);     // close this and try the next
@@ -273,7 +307,7 @@
     return 0;
 }
 
-void SeeIfUserSelectingRGBValues(point_t p)
+void SeeIfUserSelectingRGBValues(point_t p, TouchCode_t touchcode)
 {
     // See if the touch is setting new RGB values
     for (int i=0; i<3; i++) {
@@ -282,7 +316,7 @@
             rgbVal[i] = mag;
             // update the RGB values
             lcd.SelectDrawingLayer(MENUS);
-            lcd.SetTextCursor(380, 255);
+            lcd.SetTextCursor(lcd.width() - 100, lcd.height() - 18);
             lcd.foreground(Blue);
             lcd.printf("(%02X,%02X,%02X)", rgbVal[0], rgbVal[1], rgbVal[2]);
             // show sample
@@ -296,45 +330,67 @@
     }
 }
 
+void ThickLine(point_t origin, point_t p)
+{
+    double angleN = 0;
+    loc_t dy = 0;
+    loc_t dx = 0;
+    point_t s = { 0, 0 };
+    point_t e = { 0, 0 };
+
+    lcd.line(origin,p, rgb);
+    INFO("   End @ (%3d,%3d) - (%3d,%3d) [%d]", origin.x, origin.y, p.x, p.y, pensize);
+    #define PI 3.14159
+    dy = p.y - origin.y;
+    dx = p.x - origin.x;
+    INFO("delta (%+3d,%+3d)", dx,dy);
+    angleN = atan2((double)(p.y-origin.y), (double)(p.x-origin.x));
+    if (pensize == 1) {
+        lcd.line(origin, p, rgb);
+    } else {
+        int thickness = pensize/2;
+        for (int l=0; l<=pensize; l++) {
+            s.x = origin.x + (l - thickness) * cos(angleN+PI/2);
+            s.y = origin.y + (l - thickness) * sin(angleN+PI/2);
+            e.x = p.x      + (l - thickness) * cos(angleN+PI/2);
+            e.y = p.y      + (l - thickness) * sin(angleN+PI/2);
+            lcd.line(s, e, rgb);
+            INFO("     %+d @ (%3d,%3d) - (%3d,%3d) a:%+3.2f:%+3.2f",
+                      l, s.x,s.y, e.x,e.y, angleN, angleN+PI/2);
+        }
+    }
+}
+
+
 void SeeIfUserDrawingOnCanvas(point_t p, TouchCode_t touchcode)
 {
     if (lcd.Intersect(canvas_rect, p)) {
         switch (selectedtooltype) {
             case dot:
-                lcd.fillcircle(p, pensize, rgb);
+                lcd.fillcircle(p, (pensize == 1) ? pensize : pensize/2, rgb);
                 break;
             case line:
                 if (touchcode == touch) {
                     lcd.fillcircle(p, 1, rgb);
                     origin = p;
-                    pc.printf("Origin @ (%3d,%3d)\r\n", p.x, p.y);
+                    INFO("Origin @ (%3d,%3d)", p.x, p.y);
                 } else if (touchcode == release) {
-                    double angleN = 0;
-                    loc_t dy = 0;
-                    loc_t dx = 0;
-                    int thickness = 0;
-                    point_t s = { 0, 0 };
-                    point_t e = { 0, 0 };
-
-                    lcd.line(origin,p, rgb);
-                    pc.printf("   End @ (%3d,%3d) - (%3d,%3d) [%d]\r\n", origin.x, origin.y, p.x, p.y, pensize);
-#define PI 3.14159
-                    dy = p.y - origin.y;
-                    dx = p.x - origin.x;
-                    printf("delta (%+3d,%+3d)\r\n", dx,dy);
-                    angleN = atan2((double)(p.y-origin.y), (double)(p.x-origin.x));
-                    thickness = pensize;
-                    for (int l=-thickness; l<=thickness; l++) {
-                        s.x = origin.x + l * cos(angleN+PI/2);
-                        s.y = origin.y + l * sin(angleN+PI/2);
-                        e.x = p.x      + l * cos(angleN+PI/2);
-                        e.y = p.y      + l * sin(angleN+PI/2);
-                        lcd.line(s, e, rgb);
-                        pc.printf("     %+d @ (%3d,%3d) - (%3d,%3d) a:%+3.2f:%+3.2f\r\n",
-                                  l, s.x,s.y, e.x,e.y, angleN, angleN+PI/2);
-                    }
+                    ThickLine(origin, p);
                 }
                 break;
+            case join:
+                if (touchcode == touch) {
+                    lcd.fillcircle(p, 1, rgb);
+                    origin = p;
+                    INFO("Origin @ (%3d,%3d)", p.x, p.y);
+                } else if (touchcode == release) {
+                    ThickLine(origin, p);
+                } else if (touchcode == held) {
+                    ThickLine(origin, p);
+                    origin = p;
+                    INFO("  held @ (%3d,%3d)", p.x, p.y);
+                }
+                break;            
             default:
                 break;
         }
@@ -347,13 +403,13 @@
     pc.baud(460800);    // I like a snappy terminal, so crank it up!
     pc.printf("\r\nRA8875 Menu - Build " __DATE__ " " __TIME__ "\r\n");
 
-    pc.printf("Turning on display\r\n");
+    INFO("Turning on display");
     lcd.init();
     menu.init();
     InitTS();
     InitDisplay();
 
-    pc.printf("processing loop...\r\n");
+    INFO("processing loop...");
 
     for (;;) {
         point_t p;
@@ -373,10 +429,10 @@
             } else {
                 // app to handle the touch
                 if (!menu.isVisible()) {
-                    SeeIfUserSelectingRGBValues(p);
+                    SeeIfUserSelectingRGBValues(p, touchcode);
                     SeeIfUserDrawingOnCanvas(p, touchcode);
                 } else { /* MENU */
-                    pc.printf("on menu - invalid x,y\r\n");
+                    WARN("on menu - invalid x,y");
                     menu.Hide();
                 }
             }