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