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
00001 /// mPaint is a simple drawing program, used to explore the touch 00002 /// APIs of the RA8875 display library. 00003 /// 00004 /// @note Copyright © 2015 by Smartware Computing, all rights reserved. 00005 /// Individuals may use this application for evaluation or non-commercial 00006 /// purposes. Within this restriction, changes may be made to this application 00007 /// as long as this copyright notice is retained. The user shall make 00008 /// clear that their work is a derived work, and not the original. 00009 /// Users of this application and sources accept this application "as is" and 00010 /// shall hold harmless Smartware Computing, for any undesired results while 00011 /// using this application - whether real or imagined. 00012 /// 00013 /// @author David Smart, Smartware Computing 00014 // 00015 // +----------------------------------------------------+ 00016 // | File Edit Pen Tools [sample](o)[rrrr][gggg][bbbb] | 00017 // +----------------------------------------------------+ 16 00018 // | | 00019 // | canvas | 00020 // | | 00021 // | | 00022 // | | 00023 // | | 00024 // | | 00025 // | | 00026 // | | 00027 // | | 00028 // +----------------------------------------------------+ 00029 // | (xxx,yyy) - (xxx,yyy) rgb (RR,GG,BB) | 00030 // +----------------------------------------------------+ 271 00031 // 0 479 00032 // 00033 #include "mbed.h" // tested with v92 00034 #include "RA8875.h" // tested with v80 00035 #include "menu.h" 00036 #include "SDFileSystem.h" 00037 #include "FATFileSystem.h" 00038 00039 00040 #define DEBUG "mPaint" 00041 // ... 00042 // INFO("Stuff to show %d", var); // new-line is automatically appended 00043 // 00044 #if (defined(DEBUG) && !defined(TARGET_LPC11U24)) 00045 #define INFO(x, ...) std::printf("[INF %s %3d] "x"\r\n", DEBUG, __LINE__, ##__VA_ARGS__); 00046 #define WARN(x, ...) std::printf("[WRN %s %3d] "x"\r\n", DEBUG, __LINE__, ##__VA_ARGS__); 00047 #define ERR(x, ...) std::printf("[ERR %s %3d] "x"\r\n", DEBUG, __LINE__, ##__VA_ARGS__); 00048 #else 00049 #define INFO(x, ...) 00050 #define WARN(x, ...) 00051 #define ERR(x, ...) 00052 #define HexDump(a, b, c) 00053 #endif 00054 00055 // Local File System: 00056 // - Store the touch screen calibration 00057 // - Capture works of art in BMP format. 00058 // LocalFileSystem local("local"); 00059 SDFileSystem sd(PTE3, PTE1, PTE2, PTE4, "sd"); 00060 00061 // The display interface 00062 //RA8875 lcd(p5, p6, p7, p12, NC, "tft"); // MOSI, MISO, SCK, /ChipSelect, /reset, name 00063 RA8875 lcd(PTD2, PTD3, PTD1, PTD0, NC, "tft"); // FRDM-K64F MOSI, MISO, SCK, /ChipSelect, /reset, name 00064 00065 00066 00067 // A monitor port for the SW developer. 00068 Serial pc(USBTX, USBRX); 00069 00070 // list of tools (dots, lines, joined lines). 00071 typedef enum { 00072 dot, // draw dots at the point 00073 line, // connected line from touch(point) to release(point) 00074 join // connected lines while held(point) 00075 } tooltype_t; // what tool are we using to draw 00076 00077 color_t rgb = Black; // the composite color value to draw in. 00078 uint8_t rgbVal[3] = { 0, 0, 0 }; // hosts each of the individual values 00079 uint32_t pensize = 1; // pensize is user selectable within a small range. 00080 tooltype_t selectedtooltype = dot; // 0:dot, 1:line, 2:join 00081 point_t origin = { 0, 0}; // tracks origin when drawing a line 00082 00083 00084 // Adjust the following if using the 800x600 display 00085 const rect_t RGBList[] = { // regions on the display for special tools 00086 { 309,0, 359,15 }, // R 00087 { 369,0, 419,15 }, // G 00088 { 429,0, 479,15 }, // B 00089 { 249,0, 299,15 } // show selected color 00090 }; 00091 const rect_t canvas_rect = { // the drawing surface 00092 0,16, 479,271 00093 }; 00094 00095 00096 00097 // File Pen Tools 00098 // New... Pensize 1 Dot 00099 // Save... Pensize 2 Line 00100 // Calibrate Pensize 4 00101 // Reset Pensize 6 00102 // Pensize 8 00103 // 00104 Menu::post_fnc_action_t File(uint32_t v); 00105 Menu::post_fnc_action_t File_New(uint32_t v); 00106 Menu::post_fnc_action_t File_Save(uint32_t v); 00107 Menu::post_fnc_action_t File_Save_All(uint32_t v); 00108 Menu::post_fnc_action_t File_Cal(uint32_t v); 00109 Menu::post_fnc_action_t File_Reset(uint32_t v); 00110 Menu::post_fnc_action_t Edit(uint32_t v); 00111 Menu::post_fnc_action_t Edit_Clear(uint32_t v); 00112 Menu::post_fnc_action_t Tools(uint32_t v); 00113 Menu::post_fnc_action_t Tools_Type(uint32_t v); 00114 Menu::post_fnc_action_t PenSize(uint32_t v); 00115 Menu::post_fnc_action_t HideMenu(uint32_t v); 00116 00117 // Some APIs 00118 extern "C" void mbed_reset(); 00119 int GetScreenCapture(void); 00120 void CalibrateTS(void); 00121 void ShowSampleRGB(void); 00122 void InitDisplay(void); 00123 00124 Menu::menu_item_t file_menu[] = { 00125 // Prompt, onPress, onHold, OnRelease, parameter, child menu 00126 { "New...", File_New, NULL, NULL, 0, NULL }, 00127 { "Save...", File_Save, NULL, NULL, 0, NULL }, 00128 { "Save all", File_Save_All, NULL, NULL, 0, NULL }, 00129 { "Calibrate", File_Cal, NULL, NULL, 0, NULL }, 00130 { "Reset", NULL, NULL, File_Reset, 0, NULL }, 00131 { NULL, NULL, NULL, NULL, 0, NULL }, 00132 }; 00133 00134 Menu::menu_item_t pen_menu[] = { 00135 { "1 pix", NULL, NULL, PenSize, 1, NULL }, 00136 { "2 pix", NULL, NULL, PenSize, 2, NULL }, 00137 { "4 pix", NULL, NULL, PenSize, 4, NULL }, 00138 { "6 pix", NULL, NULL, PenSize, 6, NULL }, 00139 { "8 pix", NULL, NULL, PenSize, 8, NULL }, 00140 { NULL, NULL, NULL, NULL, 0, NULL }, 00141 }; 00142 00143 Menu::menu_item_t tools_menu[] = { 00144 { "point", NULL, NULL, Tools_Type, dot, NULL }, 00145 { "line", NULL, NULL, Tools_Type, line, NULL }, 00146 { "join", NULL, NULL, Tools_Type, join, NULL }, 00147 { NULL, NULL, NULL, NULL, 0, NULL }, 00148 }; 00149 00150 Menu::menu_item_t menudata[] = { 00151 { "File", File, NULL, NULL, 0, file_menu }, 00152 { "Pen", NULL, NULL, NULL, 0, pen_menu }, 00153 { "Tools", NULL, NULL, NULL, 0, tools_menu }, 00154 { "Hide", NULL, NULL, HideMenu, 0, NULL }, 00155 { NULL, NULL, NULL, NULL, 0, NULL }, 00156 }; 00157 00158 Menu menu(lcd, menudata); 00159 00160 Menu::post_fnc_action_t File(uint32_t v) 00161 { 00162 (void)v; 00163 INFO("File"); 00164 return Menu::no_action; 00165 } 00166 Menu::post_fnc_action_t File_New(uint32_t v) 00167 { 00168 (void)v; 00169 INFO("File_New"); 00170 InitDisplay(); 00171 return Menu::no_action; 00172 } 00173 Menu::post_fnc_action_t File_Save(uint32_t v) 00174 { 00175 (void)v; 00176 INFO("File_Save"); 00177 RA8875::LayerMode_T l = lcd.GetLayerMode(); 00178 lcd.SetLayerMode(RA8875::ShowLayer0); 00179 GetScreenCapture(); 00180 lcd.SetLayerMode(RA8875::TransparentMode); 00181 return Menu::close_menu; 00182 } 00183 Menu::post_fnc_action_t File_Save_All(uint32_t v) 00184 { 00185 (void)v; 00186 INFO("File_Save_All"); 00187 GetScreenCapture(); 00188 return Menu::close_menu; 00189 } 00190 Menu::post_fnc_action_t File_Cal(uint32_t v) 00191 { 00192 (void)v; 00193 INFO("Tools_Cal"); 00194 CalibrateTS(); 00195 return Menu::no_action; 00196 } 00197 Menu::post_fnc_action_t File_Reset(uint32_t v) 00198 { 00199 (void)v; 00200 INFO("rebooting now..."); 00201 wait_ms(1000); 00202 NVIC_SystemReset(); // Software reset. 00203 return Menu::no_action; 00204 } 00205 Menu::post_fnc_action_t Edit(uint32_t v) 00206 { 00207 (void)v; 00208 INFO("Edit"); 00209 return Menu::no_action; 00210 } 00211 Menu::post_fnc_action_t Tools(uint32_t v) 00212 { 00213 (void)v; 00214 INFO("Tools"); 00215 return Menu::no_action; 00216 } 00217 Menu::post_fnc_action_t PenSize(uint32_t v) 00218 { 00219 pensize = v; 00220 if (pensize < 1) 00221 pensize = 1; 00222 else if (pensize > 8) 00223 pensize = 8; 00224 INFO("PenSize(%d)", pensize); 00225 ShowSampleRGB(); 00226 return Menu::close_menu; 00227 } 00228 Menu::post_fnc_action_t Tools_Type(uint32_t v) 00229 { 00230 switch (v) { 00231 case dot: 00232 case line: 00233 case join: 00234 selectedtooltype = (tooltype_t)v; 00235 break; 00236 default: 00237 break; 00238 } 00239 ShowSampleRGB(); 00240 return Menu::close_menu; 00241 } 00242 Menu::post_fnc_action_t HideMenu(uint32_t v) 00243 { 00244 (void)v; 00245 return Menu::close_menu; 00246 } 00247 00248 void ShowSampleRGB(void) 00249 { 00250 loc_t middle = (RGBList[3].p1.y + RGBList[3].p2.y)/2; 00251 lcd.fillrect(RGBList[3], Black); 00252 lcd.fillrect(RGBList[3], rgb); 00253 if (selectedtooltype == dot) { 00254 lcd.fillcircle((RGBList[3].p1.x + RGBList[3].p2.x)/2, 00255 middle, pensize, rgb); 00256 } else { 00257 lcd.fillrect(RGBList[3].p1.x,middle-pensize/2, RGBList[3].p2.x,middle+pensize/2, rgb); 00258 } 00259 } 00260 00261 void CalibrateTS(void) 00262 { 00263 FILE * fh; 00264 tpMatrix_t matrix; 00265 RetCode_t r; 00266 00267 r = lcd.TouchPanelCalibrate("Calibrate the touch panel", &matrix); 00268 INFO(" ret: %d", r); 00269 if (r == noerror) { 00270 fh = fopen("/sd/tpcal.cfg", "wb"); 00271 if (fh) { 00272 fwrite(&matrix, sizeof(tpMatrix_t), 1, fh); 00273 fclose(fh); 00274 INFO(" tp cal written."); 00275 } else { 00276 WARN(" couldn't open tpcal file."); 00277 } 00278 } else { 00279 ERR("error return: %d", r); 00280 } 00281 } 00282 00283 00284 void InitTS(void) 00285 { 00286 FILE * fh; 00287 tpMatrix_t matrix; 00288 00289 fh = fopen("/sd/tpcal.cfg", "rb"); 00290 if (fh) { 00291 fread(&matrix, sizeof(tpMatrix_t), 1, fh); 00292 fclose(fh); 00293 lcd.TouchPanelSetMatrix(&matrix); 00294 INFO(" tp cal loaded."); 00295 } else { 00296 CalibrateTS(); 00297 } 00298 } 00299 00300 00301 void InitDisplay(void) 00302 { 00303 lcd.SelectDrawingLayer(CANVAS); 00304 lcd.cls(); 00305 lcd.foreground(Blue); 00306 lcd.background(White); 00307 lcd.Backlight_u8(255); 00308 } 00309 00310 int GetScreenCapture(void) 00311 { 00312 char fqfn[50]; 00313 int i = 0; 00314 00315 INFO("Screen Capture... "); 00316 for (i=1; i< 100; i++) { 00317 snprintf(fqfn, sizeof(fqfn), "/sd/Screen%02d.bmp", i); 00318 FILE * fh = fopen(fqfn, "rb"); 00319 if (!fh) { 00320 lcd.PrintScreen(0,0,lcd.width(),lcd.height(),fqfn); 00321 INFO(" as /sd/Screen%02d.bmp", i); 00322 return i; 00323 } else { 00324 fclose(fh); // close this and try the next 00325 } 00326 } 00327 return 0; 00328 } 00329 00330 void ShowRGBSelectors(void) 00331 { 00332 uint16_t curLayer = lcd.GetDrawingLayer(); 00333 lcd.SelectDrawingLayer(MENUS); 00334 lcd.fillrect(RGBList[0], Red); 00335 lcd.fillrect(RGBList[1], Green); 00336 lcd.fillrect(RGBList[2], Blue); 00337 lcd.SelectDrawingLayer(curLayer); 00338 } 00339 00340 bool SeeIfUserSelectingRGBValues(point_t p, TouchCode_t touchcode) 00341 { 00342 static bool wasIn = false; 00343 00344 // See if the touch is setting new RGB values 00345 for (int i=0; i<3; i++) { 00346 if (lcd.Intersect(RGBList[i], p)) { 00347 uint8_t mag = (255 * (p.x - RGBList[i].p1.x)) / (RGBList[i].p2.x - RGBList[i].p1.x); 00348 wasIn = true; 00349 if (touchcode == touch) 00350 menu.Show(); 00351 else if (touchcode == release) 00352 menu.Hide(); 00353 rgbVal[i] = mag; 00354 // update the RGB values 00355 lcd.SelectDrawingLayer(MENUS); 00356 lcd.SetTextCursor(lcd.width() - 80, lcd.height() - 16); 00357 lcd.foreground(Blue); 00358 lcd.printf("(%02X,%02X,%02X)", rgbVal[0], rgbVal[1], rgbVal[2]); 00359 // show sample 00360 rgb = RGB(rgbVal[0], rgbVal[1], rgbVal[2]); 00361 ShowSampleRGB(); 00362 // 00363 lcd.SelectDrawingLayer(CANVAS); 00364 lcd.foreground(rgb); 00365 return true; 00366 } 00367 } 00368 if (wasIn) 00369 menu.Hide(); 00370 return false; 00371 } 00372 00373 void ThickLine(point_t origin, point_t p) 00374 { 00375 double angleN; 00376 loc_t dy; 00377 loc_t dx; 00378 point_t s = { 0, 0 }; 00379 point_t e = { 0, 0 }; 00380 00381 lcd.line(origin,p, rgb); 00382 INFO(" End @ (%3d,%3d) - (%3d,%3d) [%d]", origin.x, origin.y, p.x, p.y, pensize); 00383 #define PI 3.14159 00384 dy = p.y - origin.y; 00385 dx = p.x - origin.x; 00386 INFO("delta (%+3d,%+3d)", dx,dy); 00387 angleN = atan2((double)(dy), (double)(dx)); 00388 if (pensize == 1) { 00389 lcd.line(origin, p, rgb); 00390 } else { 00391 int thickness = pensize/2; 00392 for (int l=0; l<=pensize; l++) { 00393 s.x = origin.x + (l - thickness) * cos(angleN+PI/2); 00394 s.y = origin.y + (l - thickness) * sin(angleN+PI/2); 00395 e.x = p.x + (l - thickness) * cos(angleN+PI/2); 00396 e.y = p.y + (l - thickness) * sin(angleN+PI/2); 00397 lcd.line(s, e, rgb); 00398 INFO(" %+d @ (%3d,%3d) - (%3d,%3d) a:%+3.2f:%+3.2f", 00399 l, s.x,s.y, e.x,e.y, angleN, angleN+PI/2); 00400 } 00401 } 00402 } 00403 00404 00405 void SeeIfUserDrawingOnCanvas(point_t p, TouchCode_t touchcode) 00406 { 00407 if (lcd.Intersect(canvas_rect, p)) { 00408 switch (selectedtooltype) { 00409 case dot: 00410 lcd.fillcircle(p, (pensize == 1) ? pensize : pensize/2, rgb); 00411 break; 00412 case line: 00413 if (touchcode == touch) { 00414 lcd.fillcircle(p, 1, rgb); 00415 origin = p; 00416 INFO("Origin @ (%3d,%3d)", p.x, p.y); 00417 } else if (touchcode == release) { 00418 ThickLine(origin, p); 00419 } 00420 break; 00421 case join: 00422 if (touchcode == touch) { 00423 lcd.fillcircle(p, 1, rgb); 00424 origin = p; 00425 INFO("Origin @ (%3d,%3d)", p.x, p.y); 00426 } else if (touchcode == release) { 00427 ThickLine(origin, p); 00428 } else if (touchcode == held) { 00429 ThickLine(origin, p); 00430 origin = p; 00431 INFO(" held @ (%3d,%3d)", p.x, p.y); 00432 } 00433 break; 00434 default: 00435 break; 00436 } 00437 } 00438 } 00439 00440 00441 int main() 00442 { 00443 pc.baud(115200); // I like a snappy terminal, so crank it up! 00444 pc.printf("\r\nRA8875 Menu - Build " __DATE__ " " __TIME__ "\r\n"); 00445 00446 INFO("Turning on display"); 00447 lcd.init(); 00448 InitTS(); 00449 InitDisplay(); 00450 menu.init(); 00451 ShowRGBSelectors(); 00452 00453 INFO("processing loop..."); 00454 00455 for (;;) { 00456 point_t p; 00457 TouchCode_t touchcode = lcd.TouchPanelReadable(&p); 00458 00459 if (touchcode != no_touch) { 00460 int curLayer = lcd.GetDrawingLayer(); 00461 lcd.SelectDrawingLayer(MENUS); 00462 lcd.foreground(Blue); 00463 lcd.SetTextCursor(0, lcd.height() - 16); 00464 lcd.printf("(%3d,%3d) - (%3d,%3d)", origin.x, origin.y, p.x, p.y); 00465 lcd.SelectDrawingLayer(curLayer); 00466 00467 bool menuHandledIt = menu.HandledTouch(p, touchcode); 00468 if (menuHandledIt) { 00469 // menu handled it 00470 } else if (SeeIfUserSelectingRGBValues(p, touchcode)) { 00471 // that handled it. 00472 } else { 00473 SeeIfUserDrawingOnCanvas(p, touchcode); 00474 } 00475 } else { 00476 //non-touch 00477 } 00478 } 00479 } 00480 #include <stdarg.h> 00481 //Custom override for error() 00482 void error(const char* format, ...) 00483 { 00484 char sprintf_buffer[128]; 00485 00486 va_list arg; 00487 va_start(arg, format); 00488 vsprintf(sprintf_buffer, format, arg); 00489 va_end(arg); 00490 00491 fprintf(stderr, "SW err: %s", sprintf_buffer); 00492 } 00493 00494 // Reset_Handler 00495 // NMI_Handler 00496 // HardFault_Handler 00497 // MemManage_Handler 00498 // BusFault_Handler 00499 // UsageFault_Handler 00500 extern "C" void HardFault_Handler() 00501 { 00502 printf("\r\n\r\nHard Fault!\r\n"); 00503 wait_ms(500); 00504 NVIC_SystemReset(); 00505 } 00506 /* 00507 extern "C" void NMI_Handler() 00508 { 00509 printf("\r\n\r\nNMI Fault!\r\n"); 00510 wait_ms(500); 00511 NVIC_SystemReset(); 00512 } 00513 */ 00514 00515 extern "C" void MemManage_Handler() 00516 { 00517 printf("\r\n\r\nMemManage Fault!\r\n"); 00518 wait_ms(500); 00519 NVIC_SystemReset(); 00520 } 00521 extern "C" void BusFault_Handler() 00522 { 00523 printf("\r\n\r\nBusFault Fault!\r\n"); 00524 wait_ms(500); 00525 NVIC_SystemReset(); 00526 } 00527 extern "C" void UsageFault_Handler() 00528 { 00529 printf("\r\n\r\nUsageFault Fault!\r\n"); 00530 wait_ms(500); 00531 NVIC_SystemReset(); 00532 }
Generated on Sat Jul 16 2022 20:13:52 by 1.7.2