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
Diff: main.cpp
- 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(); +}