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
main.cpp
- Committer:
- WiredHome
- Date:
- 2015-01-03
- Revision:
- 3:3b214426761d
- Parent:
- 2:cf295dad3192
- Child:
- 5:3afc5780b966
File content as of revision 3:3b214426761d:
/// 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 | // | | // | | // | | // | | // | | // | | // | | // | | // +----------------------------------------------------+ // | (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 works of art 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); // list of tools (dots, lines, joined lines). typedef enum { 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 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 { 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); Menu::post_fnc_action_t HideMenu(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, dot, NULL }, { "line", NULL, NULL, Tools_Type, line, NULL }, { "join", NULL, NULL, Tools_Type, join, 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 }, { "Hide", NULL, NULL, HideMenu, 0, NULL }, { NULL, NULL, NULL, NULL, 0, NULL }, }; Menu menu(lcd, menudata); Menu::post_fnc_action_t File(uint32_t v) { (void)v; INFO("File"); return Menu::no_action; } Menu::post_fnc_action_t File_New(uint32_t v) { (void)v; INFO("File_New"); InitDisplay(); return Menu::no_action; } Menu::post_fnc_action_t File_Save(uint32_t v) { (void)v; INFO("File_Save"); 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) { (void)v; INFO("File_Save_All"); GetScreenCapture(); return Menu::close_menu; } Menu::post_fnc_action_t File_Cal(uint32_t v) { (void)v; INFO("Tools_Cal"); CalibrateTS(); return Menu::no_action; } Menu::post_fnc_action_t File_Reset(uint32_t v) { (void)v; INFO("rebooting now..."); wait_ms(1000); mbed_reset(); return Menu::no_action; } Menu::post_fnc_action_t Edit(uint32_t v) { (void)v; INFO("Edit"); return Menu::no_action; } Menu::post_fnc_action_t Tools(uint32_t v) { (void)v; INFO("Tools"); 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; INFO("PenSize(%d)", pensize); ShowSampleRGB(); return Menu::close_menu; } Menu::post_fnc_action_t Tools_Type(uint32_t v) { switch (v) { case dot: case line: case join: selectedtooltype = (tooltype_t)v; break; default: break; } ShowSampleRGB(); return Menu::close_menu; } Menu::post_fnc_action_t HideMenu(uint32_t v) { (void)v; return Menu::close_menu; } 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 == dot) { lcd.fillcircle((RGBList[3].p1.x + RGBList[3].p2.x)/2, middle, pensize, rgb); } else { lcd.fillrect(RGBList[3].p1.x,middle-pensize/2, RGBList[3].p2.x,middle+pensize/2, rgb); } } void CalibrateTS(void) { FILE * fh; tpMatrix_t matrix; RetCode_t r; r = lcd.TouchPanelCalibrate("Calibrate the touch panel", &matrix); INFO(" ret: %d", r); if (r == noerror) { fh = fopen("/local/tpcal.cfg", "wb"); if (fh) { fwrite(&matrix, sizeof(tpMatrix_t), 1, fh); fclose(fh); INFO(" tp cal written."); } else { WARN(" couldn't open tpcal file."); } } else { ERR("error return: %d", 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); INFO(" tp cal loaded."); } else { CalibrateTS(); } } void InitDisplay(void) { lcd.SelectDrawingLayer(CANVAS); lcd.cls(); lcd.foreground(Blue); lcd.background(Black); } int GetScreenCapture(void) { char fqfn[50]; int i = 0; 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,lcd.width(),lcd.height(),fqfn); INFO(" as /local/Screen%02d.bmp", i); return i; } else { fclose(fh); // close this and try the next } } return 0; } void ShowRGBSelectors(void) { uint16_t curLayer = lcd.GetDrawingLayer(); lcd.SelectDrawingLayer(MENUS); lcd.fillrect(RGBList[0], Red); lcd.fillrect(RGBList[1], Green); lcd.fillrect(RGBList[2], Blue); lcd.SelectDrawingLayer(curLayer); } bool SeeIfUserSelectingRGBValues(point_t p, TouchCode_t touchcode) { static bool wasIn = false; // 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); wasIn = true; if (touchcode == touch) menu.Show(); else if (touchcode == release) menu.Hide(); rgbVal[i] = mag; // update the RGB values lcd.SelectDrawingLayer(MENUS); lcd.SetTextCursor(lcd.width() - 80, lcd.height() - 16); 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); return true; } } if (wasIn) menu.Hide(); return false; } void ThickLine(point_t origin, point_t p) { double angleN; loc_t dy; loc_t dx; 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)(dy), (double)(dx)); 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 == 1) ? pensize : pensize/2, rgb); break; case line: 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); } 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; } } } int main() { pc.baud(460800); // I like a snappy terminal, so crank it up! pc.printf("\r\nRA8875 Menu - Build " __DATE__ " " __TIME__ "\r\n"); INFO("Turning on display"); lcd.init(); InitTS(); InitDisplay(); menu.init(); ShowRGBSelectors(); INFO("processing loop..."); 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, lcd.height() - 16); 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 if (SeeIfUserSelectingRGBValues(p, touchcode)) { // that handled it. } else { SeeIfUserDrawingOnCanvas(p, touchcode); } } 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(); }