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:
0:326a3f29e21b
Child:
1:0fdc10700ed2
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Thu Jan 01 21:54:21 2015 +0000
@@ -0,0 +1,437 @@
+//
+//
+// +----------------------------------------------------+
+// | File Edit Pen Tools  [sample](o)[rrrr][gggg][bbbb] |
+// +----------------------------------------------------+
+// |                                                    |
+// |      canvas                                        |
+// |                                                    |
+// |                                                    |
+// |                                                    |
+// |                                                    |
+// |                                                    |
+// |                                                    |
+// |                                                    |
+// |                                                    |
+// +----------------------------------------------------+
+// | (xxx,yyy) - (xxx,yyy)               rgb (RR,GG,BB) |
+// +----------------------------------------------------+
+//
+//
+#include "mbed.h"           // tested with v92
+#include "RA8875.h"         // tested with v80
+#include "menu.h"
+
+// Local File System:
+// - Store the touch screen calibration
+// - Capture image in BMP format.
+LocalFileSystem local("local");
+
+// The display interface
+RA8875 lcd(p5, p6, p7, p12, NC, "tft");    // MOSI, MISO, SCK, /ChipSelect, /reset, name
+
+// A monitor port for the SW developer.
+Serial pc(USBTX, USBRX);
+
+typedef enum {
+    dot,
+    line
+} 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
+point_t origin = { 0, 0};           // tracks origin when drawing a line
+
+
+const rect_t RGBList[] = {          // regions on the display for special tools
+    { 309,0, 359,15 },    // R
+    { 369,0, 419,15 },    // G
+    { 429,0, 479,15 },    // B
+    { 249,0, 299,15 }     // show selected color
+};
+const rect_t canvas_rect = {        // the drawing surface
+    0,16, 479,271
+};
+
+
+
+// File             Pen            Tools
+//  New...           Pensize 1      Dot
+//  Save...          Pensize 2      Line
+//  Calibrate        Pensize 4
+//  Reset            Pensize 6
+//                   Pensize 8
+//
+Menu::post_fnc_action_t File(uint32_t v);
+Menu::post_fnc_action_t File_New(uint32_t v);
+Menu::post_fnc_action_t File_Save(uint32_t v);
+Menu::post_fnc_action_t File_Save_All(uint32_t v);
+Menu::post_fnc_action_t File_Cal(uint32_t v);
+Menu::post_fnc_action_t File_Reset(uint32_t v);
+Menu::post_fnc_action_t Edit(uint32_t v);
+Menu::post_fnc_action_t Edit_Clear(uint32_t v);
+Menu::post_fnc_action_t Tools(uint32_t v);
+Menu::post_fnc_action_t Tools_Type(uint32_t v);
+Menu::post_fnc_action_t PenSize(uint32_t v);
+
+// Some APIs
+extern "C" void mbed_reset();
+int GetScreenCapture(void);
+void CalibrateTS(void);
+void ShowSampleRGB(void);
+void InitDisplay(void);
+
+Menu::menu_item_t file_menu[] = {
+    // Prompt, onPress, onHold, OnRelease, parameter, child menu
+    { "New...", File_New, NULL, NULL, 0, NULL },
+    { "Save...", File_Save, NULL, NULL, 0, NULL },
+    { "Save all", File_Save_All, NULL, NULL, 0, NULL },
+    { "Calibrate", File_Cal, NULL, NULL, 0, NULL },
+    { "Reset", NULL, NULL, File_Reset, 0, NULL },
+    { NULL, NULL, NULL, NULL, 0, NULL },
+};
+
+Menu::menu_item_t pen_menu[] = {
+    { "1 pix",  NULL, NULL, PenSize, 1, NULL },
+    { "2 pix",  NULL, NULL, PenSize, 2, NULL },
+    { "4 pix",  NULL, NULL, PenSize, 4, NULL },
+    { "6 pix",  NULL, NULL, PenSize, 6, NULL },
+    { "8 pix",  NULL, NULL, PenSize, 8, NULL },
+    { NULL, NULL, NULL, NULL, 0, NULL },
+};
+
+Menu::menu_item_t tools_menu[] = {
+    { "point", NULL, NULL, Tools_Type, 0, NULL },
+    { "line",  NULL, NULL, Tools_Type, 1, NULL },
+    { NULL, NULL, NULL, NULL, 0, NULL },
+};
+
+Menu::menu_item_t menudata[] = {
+    { "File", File, NULL, NULL, 0, file_menu },
+    { "Pen",  NULL, NULL, NULL, 0, pen_menu },
+    { "Tools", NULL, NULL, NULL, 0, tools_menu },
+    { NULL, NULL, NULL, NULL, 0, NULL },
+};
+
+Menu menu(lcd, menudata);
+
+Menu::post_fnc_action_t File(uint32_t v)
+{
+    printf("File\r\n");
+    return Menu::no_action;
+}
+Menu::post_fnc_action_t File_New(uint32_t v)
+{
+    printf("File_New\r\n");
+    InitDisplay();
+    return Menu::no_action;
+}
+Menu::post_fnc_action_t File_Save(uint32_t v)
+{
+    printf("File_Save\r\n");
+    RA8875::LayerMode_T l = lcd.GetLayerMode();
+    lcd.SetLayerMode(RA8875::ShowLayer0);
+    GetScreenCapture();
+    lcd.SetLayerMode(RA8875::TransparentMode);
+    return Menu::close_menu;
+}
+Menu::post_fnc_action_t File_Save_All(uint32_t v)
+{
+    printf("File_Save_All\r\n");
+    GetScreenCapture();
+    return Menu::close_menu;
+}
+Menu::post_fnc_action_t File_Cal(uint32_t v)
+{
+    printf("Tools_Cal\r\n");
+    CalibrateTS();
+    return Menu::no_action;
+}
+Menu::post_fnc_action_t File_Reset(uint32_t v)
+{
+    printf("rebooting now...\r\n");
+    wait_ms(1000);
+    mbed_reset();
+    return Menu::no_action;
+}
+Menu::post_fnc_action_t Edit(uint32_t v)
+{
+    printf("Edit\r\n");
+    return Menu::no_action;
+}
+Menu::post_fnc_action_t Tools(uint32_t v)
+{
+    printf("Tools\r\n");
+    return Menu::no_action;
+}
+Menu::post_fnc_action_t PenSize(uint32_t v)
+{
+    pensize = v;
+    if (pensize < 1)
+        pensize = 1;
+    else if (pensize > 8)
+        pensize = 8;
+    pc.printf("PenSize(%d)\r\n", pensize);
+    ShowSampleRGB();
+    return Menu::close_menu;
+}
+Menu::post_fnc_action_t Tools_Type(uint32_t v)
+{
+    switch (v) {
+        case 0: // dot
+        case 1: // line
+            selectedtooltype = (tooltype_t)v;
+            break;
+        default:
+            break;
+    }
+    ShowSampleRGB();
+    return Menu::close_menu;
+}
+
+void ShowSampleRGB(void)
+{
+    lcd.fillrect(RGBList[3], Black);
+    lcd.fillrect(RGBList[3], rgb);
+    if (selectedtooltype == 0) {
+        lcd.fillcircle(275,8, pensize, rgb);
+    } else {
+        lcd.fillrect(270,8-pensize/2, 280,8+pensize/2, rgb);
+    }
+}
+
+void CalibrateTS(void)
+{
+    FILE * fh;
+    tpMatrix_t matrix;
+    RetCode_t r;
+
+    r = lcd.TouchPanelCalibrate("Calibrate the touch panel", &matrix);
+    pc.printf("  ret: %d\r\n", 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");
+        } else {
+            pc.printf("  couldn't open tpcal file.\r\n");
+        }
+    } else {
+        pc.printf("error return: %d\r\n", r);
+    }
+}
+
+
+void InitTS(void)
+{
+    FILE * fh;
+    tpMatrix_t matrix;
+
+    fh = fopen("/local/tpcal.cfg", "rb");
+    if (fh) {
+        fread(&matrix, sizeof(tpMatrix_t), 1, fh);
+        fclose(fh);
+        lcd.TouchPanelSetMatrix(&matrix);
+        pc.printf("  tp cal loaded.\r\n");
+    } else {
+        CalibrateTS();
+    }
+}
+
+
+void InitDisplay(void)
+{
+    lcd.cls(3); // both layers
+    lcd.SelectDrawingLayer(CANVAS);
+    lcd.fillrect(RGBList[0], Red);
+    lcd.fillrect(RGBList[1], Green);
+    lcd.fillrect(RGBList[2], Blue);
+    lcd.foreground(Blue);
+    lcd.background(Black);
+}
+
+int GetScreenCapture(void)
+{
+    char fqfn[50];
+    int i = 0;
+
+    pc.printf("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);
+            return i;
+        } else {
+            fclose(fh);     // close this and try the next
+        }
+    }
+    return 0;
+}
+
+void SeeIfUserSelectingRGBValues(point_t p)
+{
+    // See if the touch is setting new RGB values
+    for (int i=0; i<3; i++) {
+        if (lcd.Intersect(RGBList[i], p)) {
+            uint8_t mag = (255 * (p.x - RGBList[i].p1.x)) / (RGBList[i].p2.x - RGBList[i].p1.x);
+            rgbVal[i] = mag;
+            // update the RGB values
+            lcd.SelectDrawingLayer(MENUS);
+            lcd.SetTextCursor(380, 255);
+            lcd.foreground(Blue);
+            lcd.printf("(%02X,%02X,%02X)", rgbVal[0], rgbVal[1], rgbVal[2]);
+            // show sample
+            rgb = RGB(rgbVal[0], rgbVal[1], rgbVal[2]);
+            ShowSampleRGB();
+            //
+            lcd.SelectDrawingLayer(CANVAS);
+            lcd.foreground(rgb);
+            break;
+        }
+    }
+}
+
+void SeeIfUserDrawingOnCanvas(point_t p, TouchCode_t touchcode)
+{
+    if (lcd.Intersect(canvas_rect, p)) {
+        switch (selectedtooltype) {
+            case dot:
+                lcd.fillcircle(p, pensize, 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);
+                } 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);
+                    }
+                }
+                break;
+            default:
+                break;
+        }
+    }
+}
+
+
+int main()
+{
+    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");
+    lcd.init();
+    menu.init();
+    InitTS();
+    InitDisplay();
+
+    pc.printf("processing loop...\r\n");
+
+    for (;;) {
+        point_t p;
+        TouchCode_t touchcode = lcd.TouchPanelReadable(&p);
+
+        if (touchcode != no_touch) {
+            int curLayer = lcd.GetDrawingLayer();
+            lcd.SelectDrawingLayer(MENUS);
+            lcd.foreground(Blue);
+            lcd.SetTextCursor(0, 255);
+            lcd.printf("(%3d,%3d) - (%3d,%3d)", origin.x, origin.y, p.x, p.y);
+            lcd.SelectDrawingLayer(curLayer);
+
+            bool menuHandledIt = menu.HandledTouch(p, touchcode);
+            if (menuHandledIt) {
+                // menu handled it
+            } else {
+                // app to handle the touch
+                if (!menu.isVisible()) {
+                    SeeIfUserSelectingRGBValues(p);
+                    SeeIfUserDrawingOnCanvas(p, touchcode);
+                } else { /* MENU */
+                    pc.printf("on menu - invalid x,y\r\n");
+                    menu.Hide();
+                }
+            }
+        } else {
+            //non-touch
+        }
+    }
+}
+#include <stdarg.h>
+//Custom override for error()
+void error(const char* format, ...)
+{
+    char sprintf_buffer[128];
+
+    va_list arg;
+    va_start(arg, format);
+    vsprintf(sprintf_buffer, format, arg);
+    va_end(arg);
+
+    fprintf(stderr, "SW err: %s", sprintf_buffer);
+}
+
+//            Reset_Handler
+//            NMI_Handler
+//            HardFault_Handler
+//            MemManage_Handler
+//            BusFault_Handler
+//            UsageFault_Handler
+extern "C" void HardFault_Handler()
+{
+    printf("\r\n\r\nHard Fault!\r\n");
+    wait_ms(500);
+    NVIC_SystemReset();
+}
+extern "C" void NMI_Handler()
+{
+    printf("\r\n\r\nNMI Fault!\r\n");
+    wait_ms(500);
+    NVIC_SystemReset();
+}
+extern "C" void MemManage_Handler()
+{
+    printf("\r\n\r\nMemManage Fault!\r\n");
+    wait_ms(500);
+    NVIC_SystemReset();
+}
+extern "C" void BusFault_Handler()
+{
+    printf("\r\n\r\nBusFault Fault!\r\n");
+    wait_ms(500);
+    NVIC_SystemReset();
+}
+extern "C" void UsageFault_Handler()
+{
+    printf("\r\n\r\nUsageFault Fault!\r\n");
+    wait_ms(500);
+    NVIC_SystemReset();
+}