/********************************************************************* * SEGGER Microcontroller GmbH & Co. KG * * Solutions for real time microcontroller applications * ********************************************************************** * * * (c) 1996 - 2014 SEGGER Microcontroller GmbH & Co. KG * * * * Internet: www.segger.com Support: support@segger.com * * * ********************************************************************** ** emWin V5.24 - Graphical user interface for embedded applications ** emWin is protected by international copyright laws. Knowledge of the source code may not be used to write a similar product. This file may only be used in accordance with a license and should not be re- distributed in any way. We appreciate your understanding and fairness. ---------------------------------------------------------------------- File : TOUCH_Calibrate.c Purpose : Demonstrates how a touch screen can be calibrated at run time Requirements: WindowManager - ( ) MemoryDevices - ( ) AntiAliasing - ( ) VNC-Server - ( ) PNG-Library - ( ) TrueTypeFonts - ( ) ---------------------------END-OF-HEADER------------------------------ */ #include "GUI.h" #if GUI_OS == 0 #error Multitasking sample requires task awareness (#define GUI_OS 1) #endif #ifndef WIN32 #include "RTOS.h" /* Definitions for embOS */ #define CREATE_TASK(pTCB, pName, pFunc, Priority, pStack) OS_CREATETASK(pTCB, pName, pFunc, Priority, pStack) #define START_MT() OS_Terminate(0) #define Delay(t) OS_Delay(t) #else #include "SIM.h" /* Definitions for the Win32 simulation */ #define CREATE_TASK(pTCB, pName, pFunc, Priority, pStack) SIM_CreateTask(pName, pFunc) #define START_MT() SIM_Start() #define Delay(t) SIM_Delay(t) #endif #ifndef WIN32 // // Stacks // static OS_STACKPTR int Stack_0[600]; static OS_STACKPTR int Stack_1[600]; static OS_STACKPTR int Stack_2[600]; static OS_TASK aTCB[3]; // Task control blocks #endif /******************************************************************** * * Static data * ********************************************************************* */ static const char * _acPos[] = { "(upper left position)", "(lower right position)" }; /********************************************************************* * * Static code * ********************************************************************** */ /********************************************************************* * * _WaitForPressedState * * Function description * Waits until the touch is in the given pressed state for at least 250 ms */ static void _WaitForPressedState(int Pressed) { GUI_PID_STATE State; do { GUI_TOUCH_GetState(&State); GUI_Delay(1); if (State.Pressed == Pressed) { int TimeStart = GUI_GetTime(); do { GUI_TOUCH_GetState(&State); GUI_Delay(1); if (State.Pressed != Pressed) { break; } else if ((GUI_GetTime() - 50) > TimeStart) { return; } } while (1); } } while (1); } /********************************************************************* * * _DispStringCentered * * Function description * Shows the given text horizontally and vertically centered */ static void _DispStringCentered(const char * pString) { GUI_RECT Rect; Rect.x0 = Rect.y0 = 0; Rect.x1 = LCD_GetXSize() - 1; Rect.y1 = LCD_GetYSize() - 1; GUI_DispStringInRect(pString, &Rect, GUI_TA_HCENTER | GUI_TA_VCENTER); } /********************************************************************* * * _GetPhysValues * * Function description * Asks the user to press the touch screen at the given position * and returns the physical A/D values */ static void _GetPhysValues(int LogX, int LogY, int * pPhysX, int * pPhysY, const char * pString) { char acText[] = "Press here"; GUI_RECT Rect; int FontSizeY; int Align; FontSizeY = GUI_GetFontSizeY(); GUI_Clear(); GUI_SetColor(GUI_BLACK); _DispStringCentered("Runtime calibration,\n" "please touch the screen\n" "at the center of the ring."); /* Ask user to press the touch */ // // Calculate the rectangle for the string // Rect.y0 = LogY - FontSizeY; Rect.y1 = LogY + FontSizeY; if (LogX < LCD_GetXSize() / 2) { Rect.x0 = LogX + 15; Rect.x1 = LCD_GetXSize(); Align = GUI_TA_LEFT; } else { Rect.x0 = 0; Rect.x1 = LogX - 15; Align = GUI_TA_RIGHT; } // // Show the text nearby the ring // GUI_DispStringInRect(acText, &Rect, Align | GUI_TA_TOP); GUI_DispStringInRect(pString, &Rect, Align | GUI_TA_BOTTOM); // // Draw the ring // GUI_FillCircle(LogX, LogY, 10); GUI_SetColor(GUI_WHITE); GUI_FillCircle(LogX, LogY, 5); GUI_SetColor(GUI_BLACK); // // Wait until touch is pressed // _WaitForPressedState(1); *pPhysX = GUI_TOUCH_GetxPhys(); *pPhysY = GUI_TOUCH_GetyPhys(); // // Wait until touch is released // _WaitForPressedState(0); } /******************************************************************** * * _Explain * * Funtion description * Shows a text to give a short explanation of the sample program */ static void _Explain(void) { _DispStringCentered("This sample shows how\n" "a touch screen can be\n" "calibrated at run time.\n" "Please press the touch\n" "screen to continue..."); GUI_DispStringHCenterAt("TOUCH_Calibrate", LCD_GetXSize() / 2, 5); _WaitForPressedState(1); _WaitForPressedState(0); } /********************************************************************* * * Public code * ********************************************************************** */ /********************************************************************* * * MainTask */ void _Task_0(void) { int aPhysX[2], aPhysY[2], aLogX[2], aLogY[2], i; // GUI_Init(); GUI_SetBkColor(GUI_WHITE); GUI_Clear(); GUI_SetColor(GUI_BLACK); GUI_SetFont(&GUI_Font13B_ASCII); _Explain(); /* Set the logical values */ aLogX[0] = 15; aLogY[0] = 15; aLogX[1] = LCD_GetXSize() - 15; aLogY[1] = LCD_GetYSize() - 15; /* Get the physical values of the AD converter for 2 positions */ for (i = 0; i < 2; i++) { _GetPhysValues(aLogX[i], aLogY[i], &aPhysX[i], &aPhysY[i], _acPos[i]); } /* Use the physical values to calibrate the touch screen */ GUI_TOUCH_Calibrate(0, aLogX[0], aLogX[1], aPhysX[0], aPhysX[1]); /* Calibrate X-axis */ GUI_TOUCH_Calibrate(1, aLogY[0], aLogY[1], aPhysY[0], aPhysY[1]); /* Calibrate Y-axis */ /* Display the result */ GUI_CURSOR_Show(); GUI_Clear(); _DispStringCentered("Congratulation, your\n" "touch screen has been\n" "calibrated. Please use\n" "the cursor to test\n" "the calibration..."); /* Let the user play */ while(1) { GUI_PID_STATE State; GUI_TOUCH_GetState(&State); if (State.Pressed == 1) { GUI_FillCircle(State.x, State.y, 3); } GUI_Delay(10); } } static void _GUI_Task(void) { GUI_X_ExecIdle(); GUI_SetBkColor(GUI_WHITE); GUI_SetColor(GUI_BLACK); while(1) { char s[20]; GUI_PID_STATE State; GUI_TOUCH_GetState(&State); sprintf(s,"X:%4d,Y:%4d\n",State.x,State.y); GUI_DispStringAt(s,20, 20); GUI_Exec(); // Do the background work ... Update windows etc.) GUI_X_ExecIdle(); // Nothing left to do for the moment ... Idle processing } } void MainTask(void) { // // Init GUI // GUI_Init(); //GUI_Clear(); // // Create tasks // CREATE_TASK(&aTCB[0], "Task_0", _Task_0, 80, Stack_0); CREATE_TASK(&aTCB[2], "GUI_TASK", _GUI_Task, 1, Stack_2); // // Start multitasking // START_MT(); } /*************************** End of file ****************************/