Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of RA8875 by
RA8875_Touch.cpp
00001 /// This file contains the RA8875 Touch panel methods. 00002 /// 00003 /// It combines both resistive and capacitive touch methods, and tries 00004 /// to make them nearly transparent alternates for each other. 00005 /// 00006 #include "RA8875.h" 00007 00008 #define NOTOUCH_TIMEOUT_uS 100000 00009 #define TOUCH_TICKER_uS 1000 00010 00011 00012 // Translate from FT5206 Event Flag to Touch Code to API-match the 00013 // alternate resistive touch screen driver common in the RA8875 00014 // displays. 00015 static const TouchCode_t EventFlagToTouchCode[4] = { 00016 touch, // 00b Put Down 00017 release, // 01b Put Up 00018 held, // 10b Contact 00019 no_touch // 11b Reserved 00020 }; 00021 00022 00023 RetCode_t RA8875::TouchPanelInit(void) 00024 { 00025 panelTouched = false; 00026 if (useTouchPanel == TP_CAP) { 00027 // Set to normal mode 00028 writeRegister8(FT5206_DEVICE_MODE, 0); 00029 } else { 00030 //TPCR0: Set enable bit, default sample time, wakeup, and ADC clock 00031 WriteCommand(TPCR0, TP_ENABLE | TP_ADC_SAMPLE_DEFAULT_CLKS | TP_ADC_CLKDIV_DEFAULT); 00032 // TPCR1: Set auto/manual, Ref voltage, debounce, manual mode params 00033 WriteCommand(TPCR1, TP_MODE_DEFAULT | TP_DEBOUNCE_DEFAULT); 00034 WriteCommand(INTC1, ReadCommand(INTC1) | RA8875_INT_TP); // reg INTC1: Enable Touch Panel Interrupts (D2 = 1) 00035 WriteCommand(INTC2, RA8875_INT_TP); // reg INTC2: Clear any TP interrupt flag 00036 touchSample = 0; 00037 touchState = no_cal; 00038 touchTicker.attach_us(callback(this, &RA8875::_TouchTicker), TOUCH_TICKER_uS); 00039 touchTimer.start(); 00040 touchTimer.reset(); 00041 } 00042 return noerror; 00043 } 00044 00045 00046 RetCode_t RA8875::TouchPanelInit(uint8_t bTpEnable, uint8_t bTpAutoManual, uint8_t bTpDebounce, uint8_t bTpManualMode, uint8_t bTpAdcClkDiv, uint8_t bTpAdcSampleTime) 00047 { 00048 if (useTouchPanel == TP_CAP) { 00049 TouchPanelInit(); 00050 } else { 00051 // Parameter bounds check 00052 if( \ 00053 !(bTpEnable == TP_ENABLE || bTpEnable == TP_ENABLE) || \ 00054 !(bTpAutoManual == TP_MODE_AUTO || bTpAutoManual == TP_MODE_MANUAL) || \ 00055 !(bTpDebounce == TP_DEBOUNCE_OFF || bTpDebounce == TP_DEBOUNCE_ON) || \ 00056 !(bTpManualMode <= TP_MANUAL_LATCH_Y) || \ 00057 !(bTpAdcClkDiv <= TP_ADC_CLKDIV_128) || \ 00058 !(bTpAdcSampleTime <= TP_ADC_SAMPLE_65536_CLKS) \ 00059 ) return bad_parameter; 00060 // Construct the config byte for TPCR0 and write them 00061 WriteCommand(TPCR0, bTpEnable | bTpAdcClkDiv | bTpAdcSampleTime); // Note: Wakeup is never enabled 00062 // Construct the config byte for TPCR1 and write them 00063 WriteCommand(TPCR1, bTpManualMode | bTpDebounce | bTpManualMode); // Note: Always uses internal Vref. 00064 // Set up the interrupt flag and enable bits 00065 WriteCommand(INTC1, ReadCommand(INTC1) | RA8875_INT_TP); // reg INTC1: Enable Touch Panel Interrupts (D2 = 1) 00066 WriteCommand(INTC2, RA8875_INT_TP); // reg INTC2: Clear any TP interrupt flag 00067 touchSample = 0; 00068 touchState = no_cal; 00069 if (bTpEnable == TP_ENABLE) { 00070 touchTicker.attach_us(callback(this, &RA8875::_TouchTicker), TOUCH_TICKER_uS); 00071 touchTimer.start(); 00072 touchTimer.reset(); 00073 } else { 00074 touchTicker.detach(); 00075 touchTimer.stop(); 00076 } 00077 } 00078 return noerror; 00079 } 00080 00081 00082 int RA8875::TouchChannels(void) 00083 { 00084 if (useTouchPanel == TP_CAP) { 00085 return 5; // based on the FT5206 hardware 00086 } else if (useTouchPanel == TP_RES) { 00087 return 1; // based on the RA8875 resistive touch driver 00088 } else { 00089 return 0; // it isn't enabled, so there are none. 00090 } 00091 } 00092 00093 00094 // +----------------------------------------------------+ 00095 // | | 00096 // | 1 | 00097 // | | 00098 // | | 00099 // | 2 | 00100 // | | 00101 // | | 00102 // | 3 | 00103 // | | 00104 // +----------------------------------------------------+ 00105 00106 RetCode_t RA8875::TouchPanelCalibrate(tpMatrix_t * matrix) 00107 { 00108 return TouchPanelCalibrate(NULL, matrix); 00109 } 00110 00111 RetCode_t RA8875::TouchPanelCalibrate(const char * msg, tpMatrix_t * matrix, int maxwait_s) 00112 { 00113 point_t pTest[3]; 00114 point_t pSample[3]; 00115 int x,y; 00116 Timer timeout; // timeout guards for not-installed, stuck, user not present... 00117 00118 timeout.start(); 00119 while (TouchPanelA2DFiltered(&x, &y) && timeout.read() < maxwait_s) { 00120 wait_ms(20); 00121 if (idle_callback) { 00122 if (external_abort == (*idle_callback)(touchcal_wait)) { 00123 return external_abort; 00124 } 00125 } 00126 } 00127 cls(); 00128 if (msg) 00129 puts(msg); 00130 SetTextCursor(0,height()/2); 00131 pTest[0].x = 50; 00132 pTest[0].y = 50; 00133 pTest[1].x = width() - 50; 00134 pTest[1].y = height()/2; 00135 pTest[2].x = width()/2; 00136 pTest[2].y = height() - 50; 00137 00138 for (int i=0; i<3; i++) { 00139 foreground(Blue); 00140 printf(" (%3d,%3d) => ", pTest[i].x, pTest[i].y); 00141 line(pTest[i].x-10, pTest[i].y, pTest[i].x+10, pTest[i].y, White); 00142 line(pTest[i].x, pTest[i].y-10, pTest[i].x, pTest[i].y+10, White); 00143 while (!TouchPanelA2DFiltered(&x, &y) && timeout.read() < maxwait_s) { 00144 wait_ms(20); 00145 if (idle_callback) { 00146 if (external_abort == (*idle_callback)(touchcal_wait)) { 00147 return external_abort; 00148 } 00149 } 00150 } 00151 pSample[i].x = x; 00152 pSample[i].y = y; 00153 line(pTest[i].x-10, pTest[i].y, pTest[i].x+10, pTest[i].y, Black); 00154 line(pTest[i].x, pTest[i].y-10, pTest[i].x, pTest[i].y+10, Black); 00155 foreground(Blue); 00156 printf(" (%4d,%4d)\r\n", x,y); 00157 while (TouchPanelA2DFiltered(&x, &y) && timeout.read() < maxwait_s) { 00158 wait_ms(20); 00159 if (idle_callback) { 00160 if (external_abort == (*idle_callback)(touchcal_wait)) { 00161 return external_abort; 00162 } 00163 } 00164 } 00165 for (int t=0; t<100; t++) { 00166 wait_ms(20); 00167 if (idle_callback) { 00168 if (external_abort == (*idle_callback)(touchcal_wait)) { 00169 return external_abort; 00170 } 00171 } 00172 } 00173 } 00174 if (timeout.read() >= maxwait_s) 00175 return touch_cal_timeout; 00176 else 00177 return TouchPanelComputeCalibration(pTest, pSample, matrix); 00178 } 00179 00180 00181 /********************************************************************** 00182 * 00183 * Function: TouchPanelReadable() 00184 * 00185 * Description: Given a valid set of calibration factors and a point 00186 * value reported by the touch screen, this function 00187 * calculates and returns the true (or closest to true) 00188 * display point below the spot where the touch screen 00189 * was touched. 00190 * 00191 * 00192 * 00193 * Argument(s): displayPtr (output) - Pointer to the calculated 00194 * (true) display point. 00195 * screenPtr (input) - Pointer to the reported touch 00196 * screen point. 00197 * matrixPtr (input) - Pointer to calibration factors 00198 * matrix previously calculated 00199 * from a call to 00200 * setCalibrationMatrix() 00201 * 00202 * 00203 * The function simply solves for Xd and Yd by implementing the 00204 * computations required by the translation matrix. 00205 * 00206 * /- -\ 00207 * /- -\ /- -\ | | 00208 * | | | | | Xs | 00209 * | Xd | | A B C | | | 00210 * | | = | | * | Ys | 00211 * | Yd | | D E F | | | 00212 * | | | | | 1 | 00213 * \- -/ \- -/ | | 00214 * \- -/ 00215 * 00216 * It must be kept brief to avoid consuming CPU cycles. 00217 * 00218 * Return: OK - the display point was correctly calculated 00219 * and its value is in the output argument. 00220 * NOT_OK - an error was detected and the function 00221 * failed to return a valid point. 00222 * 00223 * NOTE! NOTE! NOTE! 00224 * 00225 * setCalibrationMatrix() and getDisplayPoint() will do fine 00226 * for you as they are, provided that your digitizer 00227 * resolution does not exceed 10 bits (1024 values). Higher 00228 * resolutions may cause the integer operations to overflow 00229 * and return incorrect values. If you wish to use these 00230 * functions with digitizer resolutions of 12 bits (4096 00231 * values) you will either have to a) use 64-bit signed 00232 * integer variables and math, or b) judiciously modify the 00233 * operations to scale results by a factor of 2 or even 4. 00234 * 00235 */ 00236 TouchCode_t RA8875::TouchPanelReadable(point_t * TouchPoint) 00237 { 00238 TouchCode_t ts = no_touch; 00239 00240 if (useTouchPanel == TP_RES) { 00241 int a2dX = 0; 00242 int a2dY = 0; 00243 00244 touchInfo[0].touchID = 0; 00245 ts = TouchPanelA2DFiltered(&a2dX, &a2dY); 00246 if (ts != no_touch) { 00247 panelTouched = true; 00248 numberOfTouchPoints = 1; 00249 00250 if (tpMatrix.Divider != 0) { 00251 /* Operation order is important since we are doing integer */ 00252 /* math. Make sure you add all terms together before */ 00253 /* dividing, so that the remainder is not rounded off */ 00254 /* prematurely. */ 00255 touchInfo[0].coordinates.x = ( (tpMatrix.An * a2dX) + 00256 (tpMatrix.Bn * a2dY) + tpMatrix.Cn 00257 ) / tpMatrix.Divider ; 00258 touchInfo[0].coordinates.y = ( (tpMatrix.Dn * a2dX) + 00259 (tpMatrix.En * a2dY) + tpMatrix.Fn 00260 ) / tpMatrix.Divider ; 00261 } else { 00262 ts = no_cal; 00263 } 00264 } else { 00265 numberOfTouchPoints = 0; 00266 } 00267 touchInfo[0].touchCode = ts; 00268 } else /* (useTouchPanel == TP_CAP) */ { 00269 ; 00270 } 00271 if (panelTouched == true) { 00272 panelTouched = false; 00273 if (TouchPoint) { 00274 *TouchPoint = touchInfo[0].coordinates; 00275 ts = touchInfo[0].touchCode; 00276 } else { 00277 ts = touch; 00278 } 00279 } 00280 return ts; 00281 } 00282 00283 00284 TouchCode_t RA8875::TouchPanelGet(point_t * TouchPoint) 00285 { 00286 TouchCode_t t = no_touch; 00287 00288 while (true) { 00289 t = TouchPanelReadable(TouchPoint); 00290 if (t != no_touch) 00291 break; 00292 if (idle_callback) { 00293 if (external_abort == (*idle_callback)(touch_wait)) { 00294 return no_touch; 00295 } 00296 } 00297 } 00298 return t; 00299 } 00300 00301 // Below here are primarily "helper" functions. While many are accessible 00302 // to the user code, they usually don't need to be called. 00303 00304 RetCode_t RA8875::TouchPanelSetMatrix(tpMatrix_t * matrixPtr) 00305 { 00306 if (matrixPtr == NULL || matrixPtr->Divider == 0) 00307 return bad_parameter; 00308 memcpy(&tpMatrix, matrixPtr, sizeof(tpMatrix_t)); 00309 touchState = no_touch; 00310 return noerror; 00311 } 00312 00313 static void InsertionSort(int * buf, int bufsize) 00314 { 00315 int i, j; 00316 int temp; 00317 00318 for(i = 1; i < bufsize; i++) { 00319 temp = buf[i]; 00320 j = i; 00321 while( j && (buf[j-1] > temp) ) { 00322 buf[j] = buf[j-1]; 00323 j = j-1; 00324 } 00325 buf[j] = temp; 00326 } // End of sort 00327 } 00328 00329 00330 void RA8875::_TouchTicker(void) 00331 { 00332 if (touchTimer.read_us() > NOTOUCH_TIMEOUT_uS) { 00333 touchSample = 0; 00334 if (touchState == held) 00335 touchState = release; 00336 else 00337 touchState = no_touch; 00338 touchTimer.reset(); 00339 } 00340 } 00341 00342 TouchCode_t RA8875::TouchPanelA2DRaw(int *x, int *y) 00343 { 00344 if( (ReadCommand(INTC2) & RA8875_INT_TP) ) { // Test for TP Interrupt pending in register INTC2 00345 touchTimer.reset(); 00346 *y = ReadCommand(TPYH) << 2 | ( (ReadCommand(TPXYL) & 0xC) >> 2 ); // D[9:2] from reg TPYH, D[1:0] from reg TPXYL[3:2] 00347 *x = ReadCommand(TPXH) << 2 | ( (ReadCommand(TPXYL) & 0x3) ); // D[9:2] from reg TPXH, D[1:0] from reg TPXYL[1:0] 00348 WriteCommand(INTC2, RA8875_INT_TP); // reg INTC2: Clear that TP interrupt flag 00349 touchState = touch; 00350 } else { 00351 touchState = no_touch; 00352 } 00353 return touchState; 00354 } 00355 00356 TouchCode_t RA8875::TouchPanelA2DFiltered(int *x, int *y) 00357 { 00358 static int xbuf[TPBUFSIZE], ybuf[TPBUFSIZE]; 00359 static int lastX, lastY; 00360 int i, j; 00361 TouchCode_t ret = touchState; 00362 00363 if( (ReadCommand(INTC2) & RA8875_INT_TP) ) { // Test for TP Interrupt pending in register INTC2 00364 touchTimer.reset(); 00365 // Get the next data samples 00366 ybuf[touchSample] = ReadCommand(TPYH) << 2 | ( (ReadCommand(TPXYL) & 0xC) >> 2 ); // D[9:2] from reg TPYH, D[1:0] from reg TPXYL[3:2] 00367 xbuf[touchSample] = ReadCommand(TPXH) << 2 | ( (ReadCommand(TPXYL) & 0x3) ); // D[9:2] from reg TPXH, D[1:0] from reg TPXYL[1:0] 00368 // Check for a complete set 00369 if(++touchSample == TPBUFSIZE) { 00370 // Buffers are full, so process them using Finn's method described in Analog Dialogue No. 44, Feb 2010 00371 // This requires sorting the samples in order of size, then discarding the top 25% and 00372 // bottom 25% as noise spikes. Finally, the middle 50% of the values are averaged to 00373 // reduce Gaussian noise. 00374 #if 1 00375 InsertionSort(ybuf, TPBUFSIZE); 00376 InsertionSort(xbuf, TPBUFSIZE); 00377 #else 00378 // Sort the Y buffer using an Insertion Sort 00379 for(i = 1; i <= TPBUFSIZE; i++) { 00380 temp = ybuf[i]; 00381 j = i; 00382 while( j && (ybuf[j-1] > temp) ) { 00383 ybuf[j] = ybuf[j-1]; 00384 j = j-1; 00385 } 00386 ybuf[j] = temp; 00387 } // End of Y sort 00388 // Sort the X buffer the same way 00389 for(i = 1; i <= TPBUFSIZE; i++) { 00390 temp = xbuf[i]; 00391 j = i; 00392 while( j && (xbuf[j-1] > temp) ) { 00393 xbuf[j] = xbuf[j-1]; 00394 j = j-1; 00395 } 00396 xbuf[j] = temp; 00397 } // End of X sort 00398 #endif 00399 // Average the middle half of the Y values and report them 00400 j = 0; 00401 for(i = (TPBUFSIZE/4) - 1; i < TPBUFSIZE - TPBUFSIZE/4; i++ ) { 00402 j += ybuf[i]; 00403 } 00404 *y = lastY = j * (float)2/TPBUFSIZE; // This is the average 00405 // Average the middle half of the X values and report them 00406 j = 0; 00407 for(i = (TPBUFSIZE/4) - 1; i < TPBUFSIZE - TPBUFSIZE/4; i++ ) { 00408 j += xbuf[i]; 00409 } 00410 *x = lastX = j * (float)2/TPBUFSIZE; // This is the average 00411 // Tidy up and return 00412 if (touchState == touch || touchState == held) 00413 touchState = held; 00414 else 00415 touchState = touch; 00416 ret = touchState; 00417 touchSample = 0; // Ready to start on the next set of data samples 00418 } else { 00419 // Buffer not yet full, so do not return any results yet 00420 if (touchState == touch || touchState == held) { 00421 *x = lastX; 00422 *y = lastY; 00423 ret = touchState = held; 00424 } 00425 } 00426 WriteCommand(INTC2, RA8875_INT_TP); // reg INTC2: Clear that TP interrupt flag 00427 } // End of initial if -- data has been read and processed 00428 else { 00429 if (touchState == touch || touchState == held) { 00430 *x = lastX; 00431 *y = lastY; 00432 ret = touchState = held; 00433 } else if (touchState == release) { 00434 *x = lastX; 00435 *y = lastY; 00436 ret = release; 00437 touchState = no_touch; 00438 } 00439 } 00440 return ret; 00441 } 00442 00443 /* The following section is derived from Carlos E. Vidales. 00444 * 00445 * Copyright (c) 2001, Carlos E. Vidales. All rights reserved. 00446 * 00447 * This sample program was written and put in the public domain 00448 * by Carlos E. Vidales. The program is provided "as is" 00449 * without warranty of any kind, either expressed or implied. 00450 * If you choose to use the program within your own products 00451 * you do so at your own risk, and assume the responsibility 00452 * for servicing, repairing or correcting the program should 00453 * it prove defective in any manner. 00454 * You may copy and distribute the program's source code in any 00455 * medium, provided that you also include in each copy an 00456 * appropriate copyright notice and disclaimer of warranty. 00457 * You may also modify this program and distribute copies of 00458 * it provided that you include prominent notices stating 00459 * that you changed the file(s) and the date of any change, 00460 * and that you do not charge any royalties or licenses for 00461 * its use. 00462 * 00463 * This file contains functions that implement calculations 00464 * necessary to obtain calibration factors for a touch screen 00465 * that suffers from multiple distortion effects: namely, 00466 * translation, scaling and rotation. 00467 * 00468 * The following set of equations represent a valid display 00469 * point given a corresponding set of touch screen points: 00470 * 00471 * /- -\ 00472 * /- -\ /- -\ | | 00473 * | | | | | Xs | 00474 * | Xd | | A B C | | | 00475 * | | = | | * | Ys | 00476 * | Yd | | D E F | | | 00477 * | | | | | 1 | 00478 * \- -/ \- -/ | | 00479 * \- -/ 00480 * where: 00481 * (Xd,Yd) represents the desired display point 00482 * coordinates, 00483 * (Xs,Ys) represents the available touch screen 00484 * coordinates, and the matrix 00485 * /- -\ 00486 * |A,B,C| 00487 * |D,E,F| represents the factors used to translate 00488 * \- -/ the available touch screen point values 00489 * into the corresponding display 00490 * coordinates. 00491 * Note that for practical considerations, the utilities 00492 * within this file do not use the matrix coefficients as 00493 * defined above, but instead use the following 00494 * equivalents, since floating point math is not used: 00495 * A = An/Divider 00496 * B = Bn/Divider 00497 * C = Cn/Divider 00498 * D = Dn/Divider 00499 * E = En/Divider 00500 * F = Fn/Divider 00501 * The functions provided within this file are: 00502 * setCalibrationMatrix() - calculates the set of factors 00503 * in the above equation, given 00504 * three sets of test points. 00505 * getDisplayPoint() - returns the actual display 00506 * coordinates, given a set of 00507 * touch screen coordinates. 00508 * translateRawScreenCoordinates() - helper function to transform 00509 * raw screen points into values 00510 * scaled to the desired display 00511 * resolution. 00512 */ 00513 00514 /********************************************************************** 00515 * 00516 * Function: setCalibrationMatrix() 00517 * 00518 * Description: Calling this function with valid input data 00519 * in the display and screen input arguments 00520 * causes the calibration factors between the 00521 * screen and display points to be calculated, 00522 * and the output argument - matrixPtr - to be 00523 * populated. 00524 * 00525 * This function needs to be called only when new 00526 * calibration factors are desired. 00527 * 00528 * 00529 * Argument(s): displayPtr (input) - Pointer to an array of three 00530 * sample, reference points. 00531 * screenPtr (input) - Pointer to the array of touch 00532 * screen points corresponding 00533 * to the reference display points. 00534 * matrixPtr (output) - Pointer to the calibration 00535 * matrix computed for the set 00536 * of points being provided. 00537 * 00538 * 00539 * From the article text, recall that the matrix coefficients are 00540 * resolved to be the following: 00541 * 00542 * 00543 * Divider = (Xs0 - Xs2)*(Ys1 - Ys2) - (Xs1 - Xs2)*(Ys0 - Ys2) 00544 * 00545 * 00546 * 00547 * (Xd0 - Xd2)*(Ys1 - Ys2) - (Xd1 - Xd2)*(Ys0 - Ys2) 00548 * A = --------------------------------------------------- 00549 * Divider 00550 * 00551 * 00552 * (Xs0 - Xs2)*(Xd1 - Xd2) - (Xd0 - Xd2)*(Xs1 - Xs2) 00553 * B = --------------------------------------------------- 00554 * Divider 00555 * 00556 * 00557 * Ys0*(Xs2*Xd1 - Xs1*Xd2) + 00558 * Ys1*(Xs0*Xd2 - Xs2*Xd0) + 00559 * Ys2*(Xs1*Xd0 - Xs0*Xd1) 00560 * C = --------------------------------------------------- 00561 * Divider 00562 * 00563 * 00564 * (Yd0 - Yd2)*(Ys1 - Ys2) - (Yd1 - Yd2)*(Ys0 - Ys2) 00565 * D = --------------------------------------------------- 00566 * Divider 00567 * 00568 * 00569 * (Xs0 - Xs2)*(Yd1 - Yd2) - (Yd0 - Yd2)*(Xs1 - Xs2) 00570 * E = --------------------------------------------------- 00571 * Divider 00572 * 00573 * 00574 * Ys0*(Xs2*Yd1 - Xs1*Yd2) + 00575 * Ys1*(Xs0*Yd2 - Xs2*Yd0) + 00576 * Ys2*(Xs1*Yd0 - Xs0*Yd1) 00577 * F = --------------------------------------------------- 00578 * Divider 00579 * 00580 * 00581 * Return: OK - the calibration matrix was correctly 00582 * calculated and its value is in the 00583 * output argument. 00584 * NOT_OK - an error was detected and the 00585 * function failed to return a valid 00586 * set of matrix values. 00587 * The only time this sample code returns 00588 * NOT_OK is when Divider == 0 00589 * 00590 * 00591 * 00592 * NOTE! NOTE! NOTE! 00593 * 00594 * setCalibrationMatrix() and getDisplayPoint() will do fine 00595 * for you as they are, provided that your digitizer 00596 * resolution does not exceed 10 bits (1024 values). Higher 00597 * resolutions may cause the integer operations to overflow 00598 * and return incorrect values. If you wish to use these 00599 * functions with digitizer resolutions of 12 bits (4096 00600 * values) you will either have to a) use 64-bit signed 00601 * integer variables and math, or b) judiciously modify the 00602 * operations to scale results by a factor of 2 or even 4. 00603 * 00604 */ 00605 RetCode_t RA8875::TouchPanelComputeCalibration(point_t * displayPtr, point_t * screenPtr, tpMatrix_t * matrixPtr) 00606 { 00607 RetCode_t retValue = noerror; 00608 00609 tpMatrix.Divider = ((screenPtr[0].x - screenPtr[2].x) * (screenPtr[1].y - screenPtr[2].y)) - 00610 ((screenPtr[1].x - screenPtr[2].x) * (screenPtr[0].y - screenPtr[2].y)) ; 00611 00612 if( tpMatrix.Divider == 0 ) { 00613 retValue = bad_parameter; 00614 } else { 00615 tpMatrix.An = ((displayPtr[0].x - displayPtr[2].x) * (screenPtr[1].y - screenPtr[2].y)) - 00616 ((displayPtr[1].x - displayPtr[2].x) * (screenPtr[0].y - screenPtr[2].y)) ; 00617 00618 tpMatrix.Bn = ((screenPtr[0].x - screenPtr[2].x) * (displayPtr[1].x - displayPtr[2].x)) - 00619 ((displayPtr[0].x - displayPtr[2].x) * (screenPtr[1].x - screenPtr[2].x)) ; 00620 00621 tpMatrix.Cn = (screenPtr[2].x * displayPtr[1].x - screenPtr[1].x * displayPtr[2].x) * screenPtr[0].y + 00622 (screenPtr[0].x * displayPtr[2].x - screenPtr[2].x * displayPtr[0].x) * screenPtr[1].y + 00623 (screenPtr[1].x * displayPtr[0].x - screenPtr[0].x * displayPtr[1].x) * screenPtr[2].y ; 00624 00625 tpMatrix.Dn = ((displayPtr[0].y - displayPtr[2].y) * (screenPtr[1].y - screenPtr[2].y)) - 00626 ((displayPtr[1].y - displayPtr[2].y) * (screenPtr[0].y - screenPtr[2].y)) ; 00627 00628 tpMatrix.En = ((screenPtr[0].x - screenPtr[2].x) * (displayPtr[1].y - displayPtr[2].y)) - 00629 ((displayPtr[0].y - displayPtr[2].y) * (screenPtr[1].x - screenPtr[2].x)) ; 00630 00631 tpMatrix.Fn = (screenPtr[2].x * displayPtr[1].y - screenPtr[1].x * displayPtr[2].y) * screenPtr[0].y + 00632 (screenPtr[0].x * displayPtr[2].y - screenPtr[2].x * displayPtr[0].y) * screenPtr[1].y + 00633 (screenPtr[1].x * displayPtr[0].y - screenPtr[0].x * displayPtr[1].y) * screenPtr[2].y ; 00634 touchState = no_touch; 00635 if (matrixPtr) 00636 memcpy(matrixPtr, &tpMatrix, sizeof(tpMatrix_t)); 00637 } 00638 return( retValue ) ; 00639 } 00640 00641 ////////////////// Capacitive Touch Panel 00642 00643 uint8_t RA8875::readRegister8(uint8_t reg) { 00644 char val; 00645 00646 m_i2c->write(m_addr, (const char *)®, 1); 00647 m_i2c->read(m_addr, &val, 1); 00648 return (uint8_t)val; 00649 } 00650 00651 void RA8875::writeRegister8(uint8_t reg, uint8_t val) { 00652 char data[2]; 00653 00654 data[0] = (char)reg; 00655 data[1] = (char)val; 00656 m_i2c->write((int)FT5206_I2C_ADDRESS, data, 2); 00657 } 00658 00659 00660 // Interrupt for touch detection 00661 void RA8875::TouchPanelISR(void) 00662 { 00663 getTouchPositions(); 00664 panelTouched = true; 00665 } 00666 00667 uint8_t RA8875::getTouchPositions(void) { 00668 uint8_t valXH; 00669 uint8_t valYH; 00670 00671 numberOfTouchPoints = readRegister8(FT5206_TD_STATUS) & 0xF; 00672 gesture = readRegister8(FT5206_GEST_ID); 00673 00674 // If the switch statement was based only on numberOfTouchPoints, it would not 00675 // be able to generate notification for 'release' events (as it is no longer touched). 00676 // Therefore, forcing a 5, and it intentially falls through each lower case. 00677 switch (5) { // numberOfTouchPoints 00678 case 5: 00679 valXH = readRegister8(FT5206_TOUCH5_XH); 00680 valYH = readRegister8(FT5206_TOUCH5_YH); 00681 touchInfo[4].touchCode = EventFlagToTouchCode[valXH >> 6]; 00682 touchInfo[4].touchID = (valYH >> 4); 00683 touchInfo[4].coordinates.x = (valXH & 0x0f)*256 + readRegister8(FT5206_TOUCH5_XL); 00684 touchInfo[4].coordinates.y = (valYH & 0x0f)*256 + readRegister8(FT5206_TOUCH5_YL); 00685 case 4: 00686 valXH = readRegister8(FT5206_TOUCH4_XH); 00687 valYH = readRegister8(FT5206_TOUCH4_YH); 00688 touchInfo[3].touchCode = EventFlagToTouchCode[valXH >> 6]; 00689 touchInfo[3].touchID = (valYH >> 4); 00690 touchInfo[3].coordinates.x = (readRegister8(FT5206_TOUCH4_XH) & 0x0f)*256 + readRegister8(FT5206_TOUCH4_XL); 00691 touchInfo[3].coordinates.y = (valYH & 0x0f)*256 + readRegister8(FT5206_TOUCH4_YL); 00692 case 3: 00693 valXH = readRegister8(FT5206_TOUCH3_XH); 00694 valYH = readRegister8(FT5206_TOUCH3_YH); 00695 touchInfo[2].touchCode = EventFlagToTouchCode[valXH >> 6]; 00696 touchInfo[2].touchID = (valYH >> 4); 00697 touchInfo[2].coordinates.x = (readRegister8(FT5206_TOUCH3_XH) & 0x0f)*256 + readRegister8(FT5206_TOUCH3_XL); 00698 touchInfo[2].coordinates.y = (valYH & 0x0f)*256 + readRegister8(FT5206_TOUCH3_YL); 00699 case 2: 00700 valXH = readRegister8(FT5206_TOUCH2_XH); 00701 valYH = readRegister8(FT5206_TOUCH2_YH); 00702 touchInfo[1].touchCode = EventFlagToTouchCode[valXH >> 6]; 00703 touchInfo[1].touchID = (valYH >> 4); 00704 touchInfo[1].coordinates.x = (readRegister8(FT5206_TOUCH2_XH) & 0x0f)*256 + readRegister8(FT5206_TOUCH2_XL); 00705 touchInfo[1].coordinates.y = (valYH & 0x0f)*256 + readRegister8(FT5206_TOUCH2_YL); 00706 case 1: 00707 valXH = readRegister8(FT5206_TOUCH1_XH); 00708 valYH = readRegister8(FT5206_TOUCH1_YH); 00709 touchInfo[0].touchCode = EventFlagToTouchCode[valXH >> 6]; 00710 touchInfo[0].touchID = (valYH >> 4); 00711 touchInfo[0].coordinates.x = (readRegister8(FT5206_TOUCH1_XH) & 0x0f)*256 + readRegister8(FT5206_TOUCH1_XL); 00712 touchInfo[0].coordinates.y = (valYH & 0x0f)*256 + readRegister8(FT5206_TOUCH1_YL); 00713 break; 00714 default: 00715 break; 00716 } 00717 return numberOfTouchPoints; 00718 } 00719 00720 // #### end of touch panel code additions
Generated on Tue Jul 12 2022 19:25:30 by
