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 Jul 25 10:55:58 2016 +0000
Revision:
123:2f45e80fec5f
Parent:
108:7415c405ee08
Child:
124:1690a7ae871c
Added idle callback - when the RA8875 driver is stuck waiting on the HW, or on a long timeout, it can call an optional callback. This could be used for maintaining the Watchdog, or other activities.

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