Library to control a Graphics TFT connected to 4-wire SPI - revised for the Raio RA8875 Display Controller.

Dependents:   FRDM_RA8875_mPaint RA8875_Demo RA8875_KeyPadDemo SignalGenerator ... more

Fork of SPI_TFT by Peter Drescher

See Components - RA8875 Based Display

Enhanced touch-screen support - where it previous supported both the Resistive Touch and Capacitive Touch based on the FT5206 Touch Controller, now it also has support for the GSL1680 Touch Controller.

Offline Help Manual (Windows chm)

/media/uploads/WiredHome/ra8875.zip.bin (download, rename to .zip and unzip)

Committer:
WiredHome
Date:
Mon Mar 14 02:20:40 2016 +0000
Revision:
108:7415c405ee08
Parent:
103:7e0464ca6c5c
Child:
123:2f45e80fec5f
corrected a buffer overrun in the InsertionSort function of RA8875_Touch.cpp. Thanks to Michael Dinning for reporting it.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
WiredHome 78:faf49c381591 1 /// This file contains the RA8875 Touch panel methods.
WiredHome 78:faf49c381591 2 ///
WiredHome 78:faf49c381591 3
WiredHome 78:faf49c381591 4 #include "RA8875.h"
WiredHome 78:faf49c381591 5
WiredHome 83:7bad0068cca0 6 #define NOTOUCH_TIMEOUT_uS 100000
WiredHome 83:7bad0068cca0 7 #define TOUCH_TICKER_uS 1000
WiredHome 83:7bad0068cca0 8
WiredHome 78:faf49c381591 9 // ### Touch Panel support code additions begin here
WiredHome 78:faf49c381591 10
WiredHome 78:faf49c381591 11 RetCode_t RA8875::TouchPanelInit(void)
WiredHome 78:faf49c381591 12 {
WiredHome 78:faf49c381591 13 //TPCR0: Set enable bit, default sample time, wakeup, and ADC clock
WiredHome 78:faf49c381591 14 WriteCommand(TPCR0, TP_ENABLE | TP_ADC_SAMPLE_DEFAULT_CLKS | TP_ADC_CLKDIV_DEFAULT);
WiredHome 78:faf49c381591 15 // TPCR1: Set auto/manual, Ref voltage, debounce, manual mode params
WiredHome 78:faf49c381591 16 WriteCommand(TPCR1, TP_MODE_DEFAULT | TP_DEBOUNCE_DEFAULT);
WiredHome 78:faf49c381591 17 WriteCommand(INTC1, ReadCommand(INTC1) | RA8875_INT_TP); // reg INTC1: Enable Touch Panel Interrupts (D2 = 1)
WiredHome 78:faf49c381591 18 WriteCommand(INTC2, RA8875_INT_TP); // reg INTC2: Clear any TP interrupt flag
WiredHome 83:7bad0068cca0 19 touchSample = 0;
WiredHome 83:7bad0068cca0 20 touchState = no_cal;
WiredHome 83:7bad0068cca0 21 touchTicker.attach_us(this, &RA8875::_TouchTicker, TOUCH_TICKER_uS);
WiredHome 83:7bad0068cca0 22 touchTimer.start();
WiredHome 83:7bad0068cca0 23 touchTimer.reset();
WiredHome 78:faf49c381591 24 return noerror;
WiredHome 78:faf49c381591 25 }
WiredHome 78:faf49c381591 26
WiredHome 78:faf49c381591 27 RetCode_t RA8875::TouchPanelInit(uint8_t bTpEnable, uint8_t bTpAutoManual, uint8_t bTpDebounce, uint8_t bTpManualMode, uint8_t bTpAdcClkDiv, uint8_t bTpAdcSampleTime)
WiredHome 78:faf49c381591 28 {
WiredHome 78:faf49c381591 29 // Parameter bounds check
WiredHome 78:faf49c381591 30 if( \
WiredHome 78:faf49c381591 31 !(bTpEnable == TP_ENABLE || bTpEnable == TP_ENABLE) || \
WiredHome 78:faf49c381591 32 !(bTpAutoManual == TP_MODE_AUTO || bTpAutoManual == TP_MODE_MANUAL) || \
WiredHome 78:faf49c381591 33 !(bTpDebounce == TP_DEBOUNCE_OFF || bTpDebounce == TP_DEBOUNCE_ON) || \
WiredHome 78:faf49c381591 34 !(bTpManualMode <= TP_MANUAL_LATCH_Y) || \
WiredHome 78:faf49c381591 35 !(bTpAdcClkDiv <= TP_ADC_CLKDIV_128) || \
WiredHome 78:faf49c381591 36 !(bTpAdcSampleTime <= TP_ADC_SAMPLE_65536_CLKS) \
WiredHome 78:faf49c381591 37 ) return bad_parameter;
WiredHome 78:faf49c381591 38 // Construct the config byte for TPCR0 and write them
WiredHome 78:faf49c381591 39 WriteCommand(TPCR0, bTpEnable | bTpAdcClkDiv | bTpAdcSampleTime); // Note: Wakeup is never enabled
WiredHome 78:faf49c381591 40 // Construct the config byte for TPCR1 and write them
WiredHome 78:faf49c381591 41 WriteCommand(TPCR1, bTpManualMode | bTpDebounce | bTpManualMode); // Note: Always uses internal Vref.
WiredHome 78:faf49c381591 42 // Set up the interrupt flag and enable bits
WiredHome 78:faf49c381591 43 WriteCommand(INTC1, ReadCommand(INTC1) | RA8875_INT_TP); // reg INTC1: Enable Touch Panel Interrupts (D2 = 1)
WiredHome 78:faf49c381591 44 WriteCommand(INTC2, RA8875_INT_TP); // reg INTC2: Clear any TP interrupt flag
WiredHome 83:7bad0068cca0 45 touchSample = 0;
WiredHome 83:7bad0068cca0 46 touchState = no_cal;
WiredHome 83:7bad0068cca0 47 if (bTpEnable == TP_ENABLE) {
WiredHome 83:7bad0068cca0 48 touchTicker.attach_us(this, &RA8875::_TouchTicker, TOUCH_TICKER_uS);
WiredHome 83:7bad0068cca0 49 touchTimer.start();
WiredHome 83:7bad0068cca0 50 touchTimer.reset();
WiredHome 83:7bad0068cca0 51 } else {
WiredHome 83:7bad0068cca0 52 touchTicker.detach();
WiredHome 83:7bad0068cca0 53 touchTimer.stop();
WiredHome 83:7bad0068cca0 54 }
WiredHome 78:faf49c381591 55 return noerror;
WiredHome 78:faf49c381591 56 }
WiredHome 78:faf49c381591 57
WiredHome 81:01da2e34283d 58 // +----------------------------------------------------+
WiredHome 81:01da2e34283d 59 // | |
WiredHome 81:01da2e34283d 60 // | 1 |
WiredHome 81:01da2e34283d 61 // | |
WiredHome 81:01da2e34283d 62 // | |
WiredHome 81:01da2e34283d 63 // | 2 |
WiredHome 81:01da2e34283d 64 // | |
WiredHome 81:01da2e34283d 65 // | |
WiredHome 81:01da2e34283d 66 // | 3 |
WiredHome 81:01da2e34283d 67 // | |
WiredHome 81:01da2e34283d 68 // +----------------------------------------------------+
WiredHome 81:01da2e34283d 69
WiredHome 81:01da2e34283d 70
WiredHome 81:01da2e34283d 71 RetCode_t RA8875::TouchPanelCalibrate(tpMatrix_t * matrix)
WiredHome 81:01da2e34283d 72 {
WiredHome 81:01da2e34283d 73 return TouchPanelCalibrate(NULL, matrix);
WiredHome 81:01da2e34283d 74 }
WiredHome 81:01da2e34283d 75
WiredHome 81:01da2e34283d 76
WiredHome 88:bfddef6ec836 77 RetCode_t RA8875::TouchPanelCalibrate(const char * msg, tpMatrix_t * matrix, int maxwait_s)
WiredHome 81:01da2e34283d 78 {
WiredHome 81:01da2e34283d 79 point_t pTest[3];
WiredHome 81:01da2e34283d 80 point_t pSample[3];
WiredHome 83:7bad0068cca0 81 int x,y;
WiredHome 88:bfddef6ec836 82 Timer timeout; // timeout guards for not-installed, stuck, user not present...
WiredHome 81:01da2e34283d 83
WiredHome 88:bfddef6ec836 84 timeout.start();
WiredHome 88:bfddef6ec836 85 while (TouchPanelA2DFiltered(&x, &y) && timeout.read() < maxwait_s)
WiredHome 83:7bad0068cca0 86 wait_ms(20);
WiredHome 81:01da2e34283d 87 cls();
WiredHome 81:01da2e34283d 88 if (msg)
WiredHome 81:01da2e34283d 89 puts(msg);
WiredHome 81:01da2e34283d 90 SetTextCursor(0,height()/2);
WiredHome 81:01da2e34283d 91 pTest[0].x = 50; pTest[0].y = 50;
WiredHome 81:01da2e34283d 92 pTest[1].x = width() - 50; pTest[1].y = height()/2;
WiredHome 81:01da2e34283d 93 pTest[2].x = width()/2; pTest[2].y = height() - 50;
WiredHome 88:bfddef6ec836 94
WiredHome 81:01da2e34283d 95 for (int i=0; i<3; i++) {
WiredHome 81:01da2e34283d 96 foreground(Blue);
WiredHome 81:01da2e34283d 97 printf(" (%3d,%3d) => ", pTest[i].x, pTest[i].y);
WiredHome 81:01da2e34283d 98 line(pTest[i].x-10, pTest[i].y, pTest[i].x+10, pTest[i].y, White);
WiredHome 81:01da2e34283d 99 line(pTest[i].x, pTest[i].y-10, pTest[i].x, pTest[i].y+10, White);
WiredHome 88:bfddef6ec836 100 while (!TouchPanelA2DFiltered(&x, &y) && timeout.read() < maxwait_s)
WiredHome 81:01da2e34283d 101 wait_ms(20);
WiredHome 81:01da2e34283d 102 pSample[i].x = x;
WiredHome 81:01da2e34283d 103 pSample[i].y = y;
WiredHome 81:01da2e34283d 104 line(pTest[i].x-10, pTest[i].y, pTest[i].x+10, pTest[i].y, Black);
WiredHome 81:01da2e34283d 105 line(pTest[i].x, pTest[i].y-10, pTest[i].x, pTest[i].y+10, Black);
WiredHome 81:01da2e34283d 106 foreground(Blue);
WiredHome 81:01da2e34283d 107 printf(" (%4d,%4d)\r\n", x,y);
WiredHome 88:bfddef6ec836 108 while (TouchPanelA2DFiltered(&x, &y) && timeout.read() < maxwait_s)
WiredHome 81:01da2e34283d 109 wait_ms(20);
WiredHome 81:01da2e34283d 110 wait(2);
WiredHome 81:01da2e34283d 111 }
WiredHome 88:bfddef6ec836 112 if (timeout.read() >= maxwait_s)
WiredHome 88:bfddef6ec836 113 return touch_cal_timeout;
WiredHome 88:bfddef6ec836 114 else
WiredHome 88:bfddef6ec836 115 return TouchPanelComputeCalibration(pTest, pSample, matrix);
WiredHome 81:01da2e34283d 116 }
WiredHome 81:01da2e34283d 117
WiredHome 81:01da2e34283d 118
WiredHome 81:01da2e34283d 119 /**********************************************************************
WiredHome 81:01da2e34283d 120 *
WiredHome 81:01da2e34283d 121 * Function: getDisplayPoint()
WiredHome 81:01da2e34283d 122 *
WiredHome 81:01da2e34283d 123 * Description: Given a valid set of calibration factors and a point
WiredHome 81:01da2e34283d 124 * value reported by the touch screen, this function
WiredHome 81:01da2e34283d 125 * calculates and returns the true (or closest to true)
WiredHome 81:01da2e34283d 126 * display point below the spot where the touch screen
WiredHome 81:01da2e34283d 127 * was touched.
WiredHome 81:01da2e34283d 128 *
WiredHome 81:01da2e34283d 129 *
WiredHome 81:01da2e34283d 130 *
WiredHome 81:01da2e34283d 131 * Argument(s): displayPtr (output) - Pointer to the calculated
WiredHome 81:01da2e34283d 132 * (true) display point.
WiredHome 81:01da2e34283d 133 * screenPtr (input) - Pointer to the reported touch
WiredHome 81:01da2e34283d 134 * screen point.
WiredHome 81:01da2e34283d 135 * matrixPtr (input) - Pointer to calibration factors
WiredHome 81:01da2e34283d 136 * matrix previously calculated
WiredHome 81:01da2e34283d 137 * from a call to
WiredHome 81:01da2e34283d 138 * setCalibrationMatrix()
WiredHome 81:01da2e34283d 139 *
WiredHome 81:01da2e34283d 140 *
WiredHome 81:01da2e34283d 141 * The function simply solves for Xd and Yd by implementing the
WiredHome 81:01da2e34283d 142 * computations required by the translation matrix.
WiredHome 81:01da2e34283d 143 *
WiredHome 81:01da2e34283d 144 * /- -\
WiredHome 81:01da2e34283d 145 * /- -\ /- -\ | |
WiredHome 81:01da2e34283d 146 * | | | | | Xs |
WiredHome 81:01da2e34283d 147 * | Xd | | A B C | | |
WiredHome 81:01da2e34283d 148 * | | = | | * | Ys |
WiredHome 81:01da2e34283d 149 * | Yd | | D E F | | |
WiredHome 81:01da2e34283d 150 * | | | | | 1 |
WiredHome 81:01da2e34283d 151 * \- -/ \- -/ | |
WiredHome 81:01da2e34283d 152 * \- -/
WiredHome 81:01da2e34283d 153 *
WiredHome 81:01da2e34283d 154 * It must be kept brief to avoid consuming CPU cycles.
WiredHome 81:01da2e34283d 155 *
WiredHome 81:01da2e34283d 156 * Return: OK - the display point was correctly calculated
WiredHome 81:01da2e34283d 157 * and its value is in the output argument.
WiredHome 81:01da2e34283d 158 * NOT_OK - an error was detected and the function
WiredHome 81:01da2e34283d 159 * failed to return a valid point.
WiredHome 81:01da2e34283d 160 *
WiredHome 81:01da2e34283d 161 * NOTE! NOTE! NOTE!
WiredHome 81:01da2e34283d 162 *
WiredHome 81:01da2e34283d 163 * setCalibrationMatrix() and getDisplayPoint() will do fine
WiredHome 81:01da2e34283d 164 * for you as they are, provided that your digitizer
WiredHome 81:01da2e34283d 165 * resolution does not exceed 10 bits (1024 values). Higher
WiredHome 81:01da2e34283d 166 * resolutions may cause the integer operations to overflow
WiredHome 81:01da2e34283d 167 * and return incorrect values. If you wish to use these
WiredHome 81:01da2e34283d 168 * functions with digitizer resolutions of 12 bits (4096
WiredHome 81:01da2e34283d 169 * values) you will either have to a) use 64-bit signed
WiredHome 81:01da2e34283d 170 * integer variables and math, or b) judiciously modify the
WiredHome 81:01da2e34283d 171 * operations to scale results by a factor of 2 or even 4.
WiredHome 81:01da2e34283d 172 *
WiredHome 81:01da2e34283d 173 */
WiredHome 83:7bad0068cca0 174 TouchCode_t RA8875::TouchPanelReadable(point_t * TouchPoint)
WiredHome 81:01da2e34283d 175 {
WiredHome 83:7bad0068cca0 176 int a2dX = 0;
WiredHome 83:7bad0068cca0 177 int a2dY = 0;
WiredHome 81:01da2e34283d 178
WiredHome 83:7bad0068cca0 179 TouchCode_t ts = TouchPanelA2DFiltered(&a2dX, &a2dY);
WiredHome 83:7bad0068cca0 180 if (ts != no_touch) {
WiredHome 103:7e0464ca6c5c 181 if (tpMatrix.Divider != 0) {
WiredHome 103:7e0464ca6c5c 182 if (TouchPoint) {
WiredHome 103:7e0464ca6c5c 183 /* Operation order is important since we are doing integer */
WiredHome 103:7e0464ca6c5c 184 /* math. Make sure you add all terms together before */
WiredHome 103:7e0464ca6c5c 185 /* dividing, so that the remainder is not rounded off */
WiredHome 103:7e0464ca6c5c 186 /* prematurely. */
WiredHome 103:7e0464ca6c5c 187 TouchPoint->x = ( (tpMatrix.An * a2dX) +
WiredHome 103:7e0464ca6c5c 188 (tpMatrix.Bn * a2dY) +
WiredHome 103:7e0464ca6c5c 189 tpMatrix.Cn
WiredHome 103:7e0464ca6c5c 190 ) / tpMatrix.Divider ;
WiredHome 81:01da2e34283d 191
WiredHome 103:7e0464ca6c5c 192 TouchPoint->y = ( (tpMatrix.Dn * a2dX) +
WiredHome 103:7e0464ca6c5c 193 (tpMatrix.En * a2dY) +
WiredHome 103:7e0464ca6c5c 194 tpMatrix.Fn
WiredHome 103:7e0464ca6c5c 195 ) / tpMatrix.Divider ;
WiredHome 103:7e0464ca6c5c 196 }
WiredHome 81:01da2e34283d 197 } else {
WiredHome 83:7bad0068cca0 198 ts = no_cal;
WiredHome 81:01da2e34283d 199 }
WiredHome 81:01da2e34283d 200 }
WiredHome 83:7bad0068cca0 201 return ts;
WiredHome 81:01da2e34283d 202 }
WiredHome 81:01da2e34283d 203
WiredHome 81:01da2e34283d 204
WiredHome 85:022bba13c5c4 205 TouchCode_t RA8875::TouchPanelGet(point_t * TouchPoint)
WiredHome 85:022bba13c5c4 206 {
WiredHome 85:022bba13c5c4 207 TouchCode_t t;
WiredHome 85:022bba13c5c4 208
WiredHome 85:022bba13c5c4 209 do {
WiredHome 85:022bba13c5c4 210 t = TouchPanelReadable(TouchPoint);
WiredHome 85:022bba13c5c4 211 } while (t == no_touch);
WiredHome 85:022bba13c5c4 212 return t;
WiredHome 85:022bba13c5c4 213 }
WiredHome 85:022bba13c5c4 214
WiredHome 81:01da2e34283d 215 RetCode_t RA8875::TouchPanelSetMatrix(tpMatrix_t * matrixPtr)
WiredHome 81:01da2e34283d 216 {
WiredHome 81:01da2e34283d 217 if (matrixPtr == NULL || matrixPtr->Divider == 0)
WiredHome 81:01da2e34283d 218 return bad_parameter;
WiredHome 81:01da2e34283d 219 memcpy(&tpMatrix, matrixPtr, sizeof(tpMatrix_t));
WiredHome 83:7bad0068cca0 220 touchState = no_touch;
WiredHome 81:01da2e34283d 221 return noerror;
WiredHome 81:01da2e34283d 222 }
WiredHome 81:01da2e34283d 223
WiredHome 81:01da2e34283d 224
WiredHome 83:7bad0068cca0 225 static void InsertionSort(int * buf, int bufsize)
WiredHome 83:7bad0068cca0 226 {
WiredHome 83:7bad0068cca0 227 int i, j;
WiredHome 83:7bad0068cca0 228 int temp;
WiredHome 83:7bad0068cca0 229
WiredHome 108:7415c405ee08 230 for(i = 1; i < bufsize; i++) {
WiredHome 83:7bad0068cca0 231 temp = buf[i];
WiredHome 83:7bad0068cca0 232 j = i;
WiredHome 83:7bad0068cca0 233 while( j && (buf[j-1] > temp) ) {
WiredHome 83:7bad0068cca0 234 buf[j] = buf[j-1];
WiredHome 83:7bad0068cca0 235 j = j-1;
WiredHome 83:7bad0068cca0 236 }
WiredHome 83:7bad0068cca0 237 buf[j] = temp;
WiredHome 83:7bad0068cca0 238 } // End of sort
WiredHome 83:7bad0068cca0 239 }
WiredHome 83:7bad0068cca0 240
WiredHome 83:7bad0068cca0 241
WiredHome 83:7bad0068cca0 242 void RA8875::_TouchTicker(void)
WiredHome 78:faf49c381591 243 {
WiredHome 83:7bad0068cca0 244 if (touchTimer.read_us() > NOTOUCH_TIMEOUT_uS) {
WiredHome 83:7bad0068cca0 245 touchSample = 0;
WiredHome 83:7bad0068cca0 246 if (touchState == held)
WiredHome 83:7bad0068cca0 247 touchState = release;
WiredHome 83:7bad0068cca0 248 else
WiredHome 83:7bad0068cca0 249 touchState = no_touch;
WiredHome 83:7bad0068cca0 250 touchTimer.reset();
WiredHome 83:7bad0068cca0 251 }
WiredHome 83:7bad0068cca0 252 }
WiredHome 83:7bad0068cca0 253
WiredHome 83:7bad0068cca0 254 TouchCode_t RA8875::TouchPanelA2DRaw(int *x, int *y)
WiredHome 83:7bad0068cca0 255 {
WiredHome 83:7bad0068cca0 256 if( (ReadCommand(INTC2) & RA8875_INT_TP) ) { // Test for TP Interrupt pending in register INTC2
WiredHome 83:7bad0068cca0 257 touchTimer.reset();
WiredHome 83:7bad0068cca0 258 *y = ReadCommand(TPYH) << 2 | ( (ReadCommand(TPXYL) & 0xC) >> 2 ); // D[9:2] from reg TPYH, D[1:0] from reg TPXYL[3:2]
WiredHome 83:7bad0068cca0 259 *x = ReadCommand(TPXH) << 2 | ( (ReadCommand(TPXYL) & 0x3) ); // D[9:2] from reg TPXH, D[1:0] from reg TPXYL[1:0]
WiredHome 83:7bad0068cca0 260 WriteCommand(INTC2, RA8875_INT_TP); // reg INTC2: Clear that TP interrupt flag
WiredHome 83:7bad0068cca0 261 touchState = touch;
WiredHome 83:7bad0068cca0 262 } else {
WiredHome 83:7bad0068cca0 263 touchState = no_touch;
WiredHome 83:7bad0068cca0 264 }
WiredHome 83:7bad0068cca0 265 return touchState;
WiredHome 83:7bad0068cca0 266 }
WiredHome 83:7bad0068cca0 267
WiredHome 83:7bad0068cca0 268 TouchCode_t RA8875::TouchPanelA2DFiltered(int *x, int *y)
WiredHome 83:7bad0068cca0 269 {
WiredHome 83:7bad0068cca0 270 static int xbuf[TPBUFSIZE], ybuf[TPBUFSIZE];
WiredHome 83:7bad0068cca0 271 static int lastX, lastY;
WiredHome 83:7bad0068cca0 272 int i, j;
WiredHome 83:7bad0068cca0 273 TouchCode_t ret = touchState;
WiredHome 78:faf49c381591 274
WiredHome 78:faf49c381591 275 if( (ReadCommand(INTC2) & RA8875_INT_TP) ) { // Test for TP Interrupt pending in register INTC2
WiredHome 83:7bad0068cca0 276 touchTimer.reset();
WiredHome 78:faf49c381591 277 // Get the next data samples
WiredHome 83:7bad0068cca0 278 ybuf[touchSample] = ReadCommand(TPYH) << 2 | ( (ReadCommand(TPXYL) & 0xC) >> 2 ); // D[9:2] from reg TPYH, D[1:0] from reg TPXYL[3:2]
WiredHome 83:7bad0068cca0 279 xbuf[touchSample] = ReadCommand(TPXH) << 2 | ( (ReadCommand(TPXYL) & 0x3) ); // D[9:2] from reg TPXH, D[1:0] from reg TPXYL[1:0]
WiredHome 78:faf49c381591 280 // Check for a complete set
WiredHome 83:7bad0068cca0 281 if(++touchSample == TPBUFSIZE) {
WiredHome 78:faf49c381591 282 // Buffers are full, so process them using Finn's method described in Analog Dialogue No. 44, Feb 2010
WiredHome 78:faf49c381591 283 // This requires sorting the samples in order of size, then discarding the top 25% and
WiredHome 78:faf49c381591 284 // bottom 25% as noise spikes. Finally, the middle 50% of the values are averaged to
WiredHome 78:faf49c381591 285 // reduce Gaussian noise.
WiredHome 83:7bad0068cca0 286 #if 1
WiredHome 83:7bad0068cca0 287 InsertionSort(ybuf, TPBUFSIZE);
WiredHome 83:7bad0068cca0 288 InsertionSort(xbuf, TPBUFSIZE);
WiredHome 83:7bad0068cca0 289 #else
WiredHome 78:faf49c381591 290 // Sort the Y buffer using an Insertion Sort
WiredHome 78:faf49c381591 291 for(i = 1; i <= TPBUFSIZE; i++) {
WiredHome 78:faf49c381591 292 temp = ybuf[i];
WiredHome 78:faf49c381591 293 j = i;
WiredHome 78:faf49c381591 294 while( j && (ybuf[j-1] > temp) ) {
WiredHome 78:faf49c381591 295 ybuf[j] = ybuf[j-1];
WiredHome 78:faf49c381591 296 j = j-1;
WiredHome 78:faf49c381591 297 }
WiredHome 78:faf49c381591 298 ybuf[j] = temp;
WiredHome 78:faf49c381591 299 } // End of Y sort
WiredHome 78:faf49c381591 300 // Sort the X buffer the same way
WiredHome 78:faf49c381591 301 for(i = 1; i <= TPBUFSIZE; i++) {
WiredHome 78:faf49c381591 302 temp = xbuf[i];
WiredHome 78:faf49c381591 303 j = i;
WiredHome 78:faf49c381591 304 while( j && (xbuf[j-1] > temp) ) {
WiredHome 78:faf49c381591 305 xbuf[j] = xbuf[j-1];
WiredHome 78:faf49c381591 306 j = j-1;
WiredHome 78:faf49c381591 307 }
WiredHome 78:faf49c381591 308 xbuf[j] = temp;
WiredHome 78:faf49c381591 309 } // End of X sort
WiredHome 83:7bad0068cca0 310 #endif
WiredHome 78:faf49c381591 311 // Average the middle half of the Y values and report them
WiredHome 78:faf49c381591 312 j = 0;
WiredHome 78:faf49c381591 313 for(i = (TPBUFSIZE/4) - 1; i < TPBUFSIZE - TPBUFSIZE/4; i++ ) {
WiredHome 78:faf49c381591 314 j += ybuf[i];
WiredHome 78:faf49c381591 315 }
WiredHome 83:7bad0068cca0 316 *y = lastY = j * (float)2/TPBUFSIZE; // This is the average
WiredHome 78:faf49c381591 317 // Average the middle half of the X values and report them
WiredHome 78:faf49c381591 318 j = 0;
WiredHome 78:faf49c381591 319 for(i = (TPBUFSIZE/4) - 1; i < TPBUFSIZE - TPBUFSIZE/4; i++ ) {
WiredHome 78:faf49c381591 320 j += xbuf[i];
WiredHome 78:faf49c381591 321 }
WiredHome 83:7bad0068cca0 322 *x = lastX = j * (float)2/TPBUFSIZE; // This is the average
WiredHome 78:faf49c381591 323 // Tidy up and return
WiredHome 83:7bad0068cca0 324 if (touchState == touch || touchState == held)
WiredHome 83:7bad0068cca0 325 touchState = held;
WiredHome 83:7bad0068cca0 326 else
WiredHome 83:7bad0068cca0 327 touchState = touch;
WiredHome 83:7bad0068cca0 328 ret = touchState;
WiredHome 83:7bad0068cca0 329 touchSample = 0; // Ready to start on the next set of data samples
WiredHome 78:faf49c381591 330 } else {
WiredHome 78:faf49c381591 331 // Buffer not yet full, so do not return any results yet
WiredHome 83:7bad0068cca0 332 if (touchState == touch || touchState == held) {
WiredHome 83:7bad0068cca0 333 *x = lastX;
WiredHome 83:7bad0068cca0 334 *y = lastY;
WiredHome 83:7bad0068cca0 335 ret = touchState = held;
WiredHome 83:7bad0068cca0 336 }
WiredHome 78:faf49c381591 337 }
WiredHome 78:faf49c381591 338 WriteCommand(INTC2, RA8875_INT_TP); // reg INTC2: Clear that TP interrupt flag
WiredHome 78:faf49c381591 339 } // End of initial if -- data has been read and processed
WiredHome 83:7bad0068cca0 340 else {
WiredHome 83:7bad0068cca0 341 if (touchState == touch || touchState == held) {
WiredHome 83:7bad0068cca0 342 *x = lastX;
WiredHome 83:7bad0068cca0 343 *y = lastY;
WiredHome 83:7bad0068cca0 344 ret = touchState = held;
WiredHome 83:7bad0068cca0 345 } else if (touchState == release) {
WiredHome 83:7bad0068cca0 346 *x = lastX;
WiredHome 83:7bad0068cca0 347 *y = lastY;
WiredHome 83:7bad0068cca0 348 ret = release;
WiredHome 83:7bad0068cca0 349 touchState = no_touch;
WiredHome 83:7bad0068cca0 350 }
WiredHome 83:7bad0068cca0 351 }
WiredHome 83:7bad0068cca0 352 return ret;
WiredHome 78:faf49c381591 353 }
WiredHome 78:faf49c381591 354
WiredHome 78:faf49c381591 355 /* The following section is derived from Carlos E. Vidales.
WiredHome 78:faf49c381591 356 *
WiredHome 78:faf49c381591 357 * Copyright (c) 2001, Carlos E. Vidales. All rights reserved.
WiredHome 78:faf49c381591 358 *
WiredHome 78:faf49c381591 359 * This sample program was written and put in the public domain
WiredHome 78:faf49c381591 360 * by Carlos E. Vidales. The program is provided "as is"
WiredHome 78:faf49c381591 361 * without warranty of any kind, either expressed or implied.
WiredHome 78:faf49c381591 362 * If you choose to use the program within your own products
WiredHome 78:faf49c381591 363 * you do so at your own risk, and assume the responsibility
WiredHome 78:faf49c381591 364 * for servicing, repairing or correcting the program should
WiredHome 78:faf49c381591 365 * it prove defective in any manner.
WiredHome 78:faf49c381591 366 * You may copy and distribute the program's source code in any
WiredHome 78:faf49c381591 367 * medium, provided that you also include in each copy an
WiredHome 78:faf49c381591 368 * appropriate copyright notice and disclaimer of warranty.
WiredHome 78:faf49c381591 369 * You may also modify this program and distribute copies of
WiredHome 78:faf49c381591 370 * it provided that you include prominent notices stating
WiredHome 78:faf49c381591 371 * that you changed the file(s) and the date of any change,
WiredHome 78:faf49c381591 372 * and that you do not charge any royalties or licenses for
WiredHome 78:faf49c381591 373 * its use.
WiredHome 78:faf49c381591 374 *
WiredHome 78:faf49c381591 375 * This file contains functions that implement calculations
WiredHome 78:faf49c381591 376 * necessary to obtain calibration factors for a touch screen
WiredHome 78:faf49c381591 377 * that suffers from multiple distortion effects: namely,
WiredHome 78:faf49c381591 378 * translation, scaling and rotation.
WiredHome 78:faf49c381591 379 *
WiredHome 78:faf49c381591 380 * The following set of equations represent a valid display
WiredHome 78:faf49c381591 381 * point given a corresponding set of touch screen points:
WiredHome 78:faf49c381591 382 *
WiredHome 78:faf49c381591 383 * /- -\
WiredHome 78:faf49c381591 384 * /- -\ /- -\ | |
WiredHome 78:faf49c381591 385 * | | | | | Xs |
WiredHome 78:faf49c381591 386 * | Xd | | A B C | | |
WiredHome 78:faf49c381591 387 * | | = | | * | Ys |
WiredHome 78:faf49c381591 388 * | Yd | | D E F | | |
WiredHome 78:faf49c381591 389 * | | | | | 1 |
WiredHome 78:faf49c381591 390 * \- -/ \- -/ | |
WiredHome 78:faf49c381591 391 * \- -/
WiredHome 78:faf49c381591 392 * where:
WiredHome 78:faf49c381591 393 * (Xd,Yd) represents the desired display point
WiredHome 78:faf49c381591 394 * coordinates,
WiredHome 78:faf49c381591 395 * (Xs,Ys) represents the available touch screen
WiredHome 78:faf49c381591 396 * coordinates, and the matrix
WiredHome 78:faf49c381591 397 * /- -\
WiredHome 78:faf49c381591 398 * |A,B,C|
WiredHome 78:faf49c381591 399 * |D,E,F| represents the factors used to translate
WiredHome 78:faf49c381591 400 * \- -/ the available touch screen point values
WiredHome 78:faf49c381591 401 * into the corresponding display
WiredHome 78:faf49c381591 402 * coordinates.
WiredHome 78:faf49c381591 403 * Note that for practical considerations, the utilities
WiredHome 78:faf49c381591 404 * within this file do not use the matrix coefficients as
WiredHome 78:faf49c381591 405 * defined above, but instead use the following
WiredHome 78:faf49c381591 406 * equivalents, since floating point math is not used:
WiredHome 78:faf49c381591 407 * A = An/Divider
WiredHome 78:faf49c381591 408 * B = Bn/Divider
WiredHome 78:faf49c381591 409 * C = Cn/Divider
WiredHome 78:faf49c381591 410 * D = Dn/Divider
WiredHome 78:faf49c381591 411 * E = En/Divider
WiredHome 78:faf49c381591 412 * F = Fn/Divider
WiredHome 78:faf49c381591 413 * The functions provided within this file are:
WiredHome 78:faf49c381591 414 * setCalibrationMatrix() - calculates the set of factors
WiredHome 78:faf49c381591 415 * in the above equation, given
WiredHome 78:faf49c381591 416 * three sets of test points.
WiredHome 78:faf49c381591 417 * getDisplayPoint() - returns the actual display
WiredHome 78:faf49c381591 418 * coordinates, given a set of
WiredHome 78:faf49c381591 419 * touch screen coordinates.
WiredHome 78:faf49c381591 420 * translateRawScreenCoordinates() - helper function to transform
WiredHome 78:faf49c381591 421 * raw screen points into values
WiredHome 78:faf49c381591 422 * scaled to the desired display
WiredHome 78:faf49c381591 423 * resolution.
WiredHome 78:faf49c381591 424 */
WiredHome 78:faf49c381591 425
WiredHome 78:faf49c381591 426 /**********************************************************************
WiredHome 78:faf49c381591 427 *
WiredHome 78:faf49c381591 428 * Function: setCalibrationMatrix()
WiredHome 78:faf49c381591 429 *
WiredHome 78:faf49c381591 430 * Description: Calling this function with valid input data
WiredHome 78:faf49c381591 431 * in the display and screen input arguments
WiredHome 78:faf49c381591 432 * causes the calibration factors between the
WiredHome 78:faf49c381591 433 * screen and display points to be calculated,
WiredHome 78:faf49c381591 434 * and the output argument - matrixPtr - to be
WiredHome 78:faf49c381591 435 * populated.
WiredHome 78:faf49c381591 436 *
WiredHome 78:faf49c381591 437 * This function needs to be called only when new
WiredHome 78:faf49c381591 438 * calibration factors are desired.
WiredHome 78:faf49c381591 439 *
WiredHome 78:faf49c381591 440 *
WiredHome 78:faf49c381591 441 * Argument(s): displayPtr (input) - Pointer to an array of three
WiredHome 78:faf49c381591 442 * sample, reference points.
WiredHome 78:faf49c381591 443 * screenPtr (input) - Pointer to the array of touch
WiredHome 78:faf49c381591 444 * screen points corresponding
WiredHome 78:faf49c381591 445 * to the reference display points.
WiredHome 78:faf49c381591 446 * matrixPtr (output) - Pointer to the calibration
WiredHome 78:faf49c381591 447 * matrix computed for the set
WiredHome 78:faf49c381591 448 * of points being provided.
WiredHome 78:faf49c381591 449 *
WiredHome 78:faf49c381591 450 *
WiredHome 78:faf49c381591 451 * From the article text, recall that the matrix coefficients are
WiredHome 78:faf49c381591 452 * resolved to be the following:
WiredHome 78:faf49c381591 453 *
WiredHome 78:faf49c381591 454 *
WiredHome 78:faf49c381591 455 * Divider = (Xs0 - Xs2)*(Ys1 - Ys2) - (Xs1 - Xs2)*(Ys0 - Ys2)
WiredHome 78:faf49c381591 456 *
WiredHome 78:faf49c381591 457 *
WiredHome 78:faf49c381591 458 *
WiredHome 78:faf49c381591 459 * (Xd0 - Xd2)*(Ys1 - Ys2) - (Xd1 - Xd2)*(Ys0 - Ys2)
WiredHome 78:faf49c381591 460 * A = ---------------------------------------------------
WiredHome 78:faf49c381591 461 * Divider
WiredHome 78:faf49c381591 462 *
WiredHome 78:faf49c381591 463 *
WiredHome 78:faf49c381591 464 * (Xs0 - Xs2)*(Xd1 - Xd2) - (Xd0 - Xd2)*(Xs1 - Xs2)
WiredHome 78:faf49c381591 465 * B = ---------------------------------------------------
WiredHome 78:faf49c381591 466 * Divider
WiredHome 78:faf49c381591 467 *
WiredHome 78:faf49c381591 468 *
WiredHome 78:faf49c381591 469 * Ys0*(Xs2*Xd1 - Xs1*Xd2) +
WiredHome 78:faf49c381591 470 * Ys1*(Xs0*Xd2 - Xs2*Xd0) +
WiredHome 78:faf49c381591 471 * Ys2*(Xs1*Xd0 - Xs0*Xd1)
WiredHome 78:faf49c381591 472 * C = ---------------------------------------------------
WiredHome 78:faf49c381591 473 * Divider
WiredHome 78:faf49c381591 474 *
WiredHome 78:faf49c381591 475 *
WiredHome 78:faf49c381591 476 * (Yd0 - Yd2)*(Ys1 - Ys2) - (Yd1 - Yd2)*(Ys0 - Ys2)
WiredHome 78:faf49c381591 477 * D = ---------------------------------------------------
WiredHome 78:faf49c381591 478 * Divider
WiredHome 78:faf49c381591 479 *
WiredHome 78:faf49c381591 480 *
WiredHome 78:faf49c381591 481 * (Xs0 - Xs2)*(Yd1 - Yd2) - (Yd0 - Yd2)*(Xs1 - Xs2)
WiredHome 78:faf49c381591 482 * E = ---------------------------------------------------
WiredHome 78:faf49c381591 483 * Divider
WiredHome 78:faf49c381591 484 *
WiredHome 78:faf49c381591 485 *
WiredHome 78:faf49c381591 486 * Ys0*(Xs2*Yd1 - Xs1*Yd2) +
WiredHome 78:faf49c381591 487 * Ys1*(Xs0*Yd2 - Xs2*Yd0) +
WiredHome 78:faf49c381591 488 * Ys2*(Xs1*Yd0 - Xs0*Yd1)
WiredHome 78:faf49c381591 489 * F = ---------------------------------------------------
WiredHome 78:faf49c381591 490 * Divider
WiredHome 78:faf49c381591 491 *
WiredHome 78:faf49c381591 492 *
WiredHome 78:faf49c381591 493 * Return: OK - the calibration matrix was correctly
WiredHome 78:faf49c381591 494 * calculated and its value is in the
WiredHome 78:faf49c381591 495 * output argument.
WiredHome 78:faf49c381591 496 * NOT_OK - an error was detected and the
WiredHome 78:faf49c381591 497 * function failed to return a valid
WiredHome 78:faf49c381591 498 * set of matrix values.
WiredHome 78:faf49c381591 499 * The only time this sample code returns
WiredHome 78:faf49c381591 500 * NOT_OK is when Divider == 0
WiredHome 78:faf49c381591 501 *
WiredHome 78:faf49c381591 502 *
WiredHome 78:faf49c381591 503 *
WiredHome 78:faf49c381591 504 * NOTE! NOTE! NOTE!
WiredHome 78:faf49c381591 505 *
WiredHome 78:faf49c381591 506 * setCalibrationMatrix() and getDisplayPoint() will do fine
WiredHome 78:faf49c381591 507 * for you as they are, provided that your digitizer
WiredHome 78:faf49c381591 508 * resolution does not exceed 10 bits (1024 values). Higher
WiredHome 78:faf49c381591 509 * resolutions may cause the integer operations to overflow
WiredHome 78:faf49c381591 510 * and return incorrect values. If you wish to use these
WiredHome 78:faf49c381591 511 * functions with digitizer resolutions of 12 bits (4096
WiredHome 78:faf49c381591 512 * values) you will either have to a) use 64-bit signed
WiredHome 78:faf49c381591 513 * integer variables and math, or b) judiciously modify the
WiredHome 78:faf49c381591 514 * operations to scale results by a factor of 2 or even 4.
WiredHome 78:faf49c381591 515 *
WiredHome 78:faf49c381591 516 */
WiredHome 81:01da2e34283d 517 RetCode_t RA8875::TouchPanelComputeCalibration(point_t * displayPtr, point_t * screenPtr, tpMatrix_t * matrixPtr)
WiredHome 78:faf49c381591 518 {
WiredHome 78:faf49c381591 519 RetCode_t retValue = noerror;
WiredHome 78:faf49c381591 520
WiredHome 78:faf49c381591 521 tpMatrix.Divider = ((screenPtr[0].x - screenPtr[2].x) * (screenPtr[1].y - screenPtr[2].y)) -
WiredHome 78:faf49c381591 522 ((screenPtr[1].x - screenPtr[2].x) * (screenPtr[0].y - screenPtr[2].y)) ;
WiredHome 78:faf49c381591 523
WiredHome 78:faf49c381591 524 if( tpMatrix.Divider == 0 ) {
WiredHome 78:faf49c381591 525 retValue = bad_parameter;
WiredHome 78:faf49c381591 526 } else {
WiredHome 78:faf49c381591 527 tpMatrix.An = ((displayPtr[0].x - displayPtr[2].x) * (screenPtr[1].y - screenPtr[2].y)) -
WiredHome 78:faf49c381591 528 ((displayPtr[1].x - displayPtr[2].x) * (screenPtr[0].y - screenPtr[2].y)) ;
WiredHome 78:faf49c381591 529
WiredHome 78:faf49c381591 530 tpMatrix.Bn = ((screenPtr[0].x - screenPtr[2].x) * (displayPtr[1].x - displayPtr[2].x)) -
WiredHome 78:faf49c381591 531 ((displayPtr[0].x - displayPtr[2].x) * (screenPtr[1].x - screenPtr[2].x)) ;
WiredHome 78:faf49c381591 532
WiredHome 78:faf49c381591 533 tpMatrix.Cn = (screenPtr[2].x * displayPtr[1].x - screenPtr[1].x * displayPtr[2].x) * screenPtr[0].y +
WiredHome 78:faf49c381591 534 (screenPtr[0].x * displayPtr[2].x - screenPtr[2].x * displayPtr[0].x) * screenPtr[1].y +
WiredHome 78:faf49c381591 535 (screenPtr[1].x * displayPtr[0].x - screenPtr[0].x * displayPtr[1].x) * screenPtr[2].y ;
WiredHome 78:faf49c381591 536
WiredHome 78:faf49c381591 537 tpMatrix.Dn = ((displayPtr[0].y - displayPtr[2].y) * (screenPtr[1].y - screenPtr[2].y)) -
WiredHome 78:faf49c381591 538 ((displayPtr[1].y - displayPtr[2].y) * (screenPtr[0].y - screenPtr[2].y)) ;
WiredHome 78:faf49c381591 539
WiredHome 78:faf49c381591 540 tpMatrix.En = ((screenPtr[0].x - screenPtr[2].x) * (displayPtr[1].y - displayPtr[2].y)) -
WiredHome 78:faf49c381591 541 ((displayPtr[0].y - displayPtr[2].y) * (screenPtr[1].x - screenPtr[2].x)) ;
WiredHome 78:faf49c381591 542
WiredHome 78:faf49c381591 543 tpMatrix.Fn = (screenPtr[2].x * displayPtr[1].y - screenPtr[1].x * displayPtr[2].y) * screenPtr[0].y +
WiredHome 78:faf49c381591 544 (screenPtr[0].x * displayPtr[2].y - screenPtr[2].x * displayPtr[0].y) * screenPtr[1].y +
WiredHome 78:faf49c381591 545 (screenPtr[1].x * displayPtr[0].y - screenPtr[0].x * displayPtr[1].y) * screenPtr[2].y ;
WiredHome 83:7bad0068cca0 546 touchState = no_touch;
WiredHome 78:faf49c381591 547 if (matrixPtr)
WiredHome 78:faf49c381591 548 memcpy(matrixPtr, &tpMatrix, sizeof(tpMatrix_t));
WiredHome 78:faf49c381591 549 }
WiredHome 78:faf49c381591 550 return( retValue ) ;
WiredHome 78:faf49c381591 551 }
WiredHome 78:faf49c381591 552
WiredHome 78:faf49c381591 553 // #### end of touch panel code additions