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 Nov 25 19:55:17 2019 +0000
Revision:
193:74f80834d59d
Parent:
190:3132b7dfad82
Child:
196:56820026701b
Improve debouncing of resistive touch.; Minor format changes for easier maintenance.

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 124:1690a7ae871c 3 /// It combines both resistive and capacitive touch methods, and tries
WiredHome 124:1690a7ae871c 4 /// to make them nearly transparent alternates for each other.
WiredHome 124:1690a7ae871c 5 ///
WiredHome 78:faf49c381591 6 #include "RA8875.h"
WiredHome 165:695c24cc5197 7 #include "RA8875_Touch_FT5206.h"
WiredHome 165:695c24cc5197 8 #include "RA8875_Touch_GSL1680.h"
WiredHome 78:faf49c381591 9
WiredHome 83:7bad0068cca0 10 #define NOTOUCH_TIMEOUT_uS 100000
WiredHome 83:7bad0068cca0 11 #define TOUCH_TICKER_uS 1000
WiredHome 83:7bad0068cca0 12
WiredHome 171:f92c0f1f6db4 13 //#define DEBUG "TUCH"
WiredHome 154:ad2450fc3dc3 14 // ...
WiredHome 154:ad2450fc3dc3 15 // INFO("Stuff to show %d", var); // new-line is automatically appended
WiredHome 154:ad2450fc3dc3 16 //
WiredHome 154:ad2450fc3dc3 17 #if (defined(DEBUG) && !defined(TARGET_LPC11U24))
WiredHome 154:ad2450fc3dc3 18 #define INFO(x, ...) std::printf("[INF %s %4d] "x"\r\n", DEBUG, __LINE__, ##__VA_ARGS__);
WiredHome 154:ad2450fc3dc3 19 #define WARN(x, ...) std::printf("[WRN %s %4d] "x"\r\n", DEBUG, __LINE__, ##__VA_ARGS__);
WiredHome 154:ad2450fc3dc3 20 #define ERR(x, ...) std::printf("[ERR %s %4d] "x"\r\n", DEBUG, __LINE__, ##__VA_ARGS__);
WiredHome 154:ad2450fc3dc3 21 static void HexDump(const char * title, const uint8_t * p, int count)
WiredHome 154:ad2450fc3dc3 22 {
WiredHome 154:ad2450fc3dc3 23 int i;
WiredHome 154:ad2450fc3dc3 24 char buf[100] = "0000: ";
WiredHome 154:ad2450fc3dc3 25
WiredHome 154:ad2450fc3dc3 26 if (*title)
WiredHome 154:ad2450fc3dc3 27 INFO("%s", title);
WiredHome 154:ad2450fc3dc3 28 for (i=0; i<count; ) {
WiredHome 154:ad2450fc3dc3 29 sprintf(buf + strlen(buf), "%02X ", *(p+i));
WiredHome 154:ad2450fc3dc3 30 if ((++i & 0x0F) == 0x00) {
WiredHome 154:ad2450fc3dc3 31 INFO("%s", buf);
WiredHome 154:ad2450fc3dc3 32 if (i < count)
WiredHome 154:ad2450fc3dc3 33 sprintf(buf, "%04X: ", i);
WiredHome 154:ad2450fc3dc3 34 else
WiredHome 154:ad2450fc3dc3 35 buf[0] = '\0';
WiredHome 154:ad2450fc3dc3 36 }
WiredHome 154:ad2450fc3dc3 37 }
WiredHome 154:ad2450fc3dc3 38 if (strlen(buf))
WiredHome 154:ad2450fc3dc3 39 INFO("%s", buf);
WiredHome 154:ad2450fc3dc3 40 }
WiredHome 154:ad2450fc3dc3 41 #else
WiredHome 154:ad2450fc3dc3 42 #define INFO(x, ...)
WiredHome 154:ad2450fc3dc3 43 #define WARN(x, ...)
WiredHome 154:ad2450fc3dc3 44 #define ERR(x, ...)
WiredHome 154:ad2450fc3dc3 45 #define HexDump(a, b, c)
WiredHome 154:ad2450fc3dc3 46 #endif
WiredHome 154:ad2450fc3dc3 47
WiredHome 124:1690a7ae871c 48
WiredHome 78:faf49c381591 49 RetCode_t RA8875::TouchPanelInit(void)
WiredHome 78:faf49c381591 50 {
WiredHome 157:1565f38ca44b 51 RetCode_t r = noerror;
WiredHome 190:3132b7dfad82 52
WiredHome 124:1690a7ae871c 53 panelTouched = false;
WiredHome 165:695c24cc5197 54 if (useTouchPanel == TP_GSL1680) {
WiredHome 165:695c24cc5197 55 INFO("TouchPanelInit: TP_GSL1680");
WiredHome 169:1c1a495983bc 56 r = GSL1680_Init();
WiredHome 165:695c24cc5197 57 } else if (useTouchPanel == TP_FT5206) {
WiredHome 124:1690a7ae871c 58 // Set to normal mode
WiredHome 165:695c24cc5197 59 INFO("TouchPanelInit: TP_FT5206");
WiredHome 165:695c24cc5197 60 r = FT5206_Init();
WiredHome 124:1690a7ae871c 61 } else {
WiredHome 155:b3f225ae572c 62 INFO("TouchPanelInit: TP_RES");
WiredHome 124:1690a7ae871c 63 //TPCR0: Set enable bit, default sample time, wakeup, and ADC clock
WiredHome 193:74f80834d59d 64 WriteCommand(RA8875_TPCR0, TP_ENABLE | TP_ADC_SAMPLE_DEFAULT_CLKS | TP_ADC_CLKDIV_DEFAULT);
WiredHome 124:1690a7ae871c 65 // TPCR1: Set auto/manual, Ref voltage, debounce, manual mode params
WiredHome 193:74f80834d59d 66 WriteCommand(RA8875_TPCR1, TP_MODE_DEFAULT | TP_DEBOUNCE_DEFAULT);
WiredHome 193:74f80834d59d 67 WriteCommand(RA8875_INTC1, ReadCommand(RA8875_INTC1) | RA8875_INT_TP); // reg RA8875_INTC1: Enable Touch Panel Interrupts (D2 = 1)
WiredHome 193:74f80834d59d 68 WriteCommand(RA8875_INTC2, RA8875_INT_TP); // reg RA8875_INTC2: Clear any TP interrupt flag
WiredHome 124:1690a7ae871c 69 touchSample = 0;
WiredHome 124:1690a7ae871c 70 touchState = no_cal;
WiredHome 193:74f80834d59d 71 #if 0
WiredHome 181:0032d1b8f5d4 72 #if (MBED_MAJOR_VERSION >= 5) || (MBED_LIBRARY_VERSION > 127)
WiredHome 145:5eb2492acdda 73 touchTicker.attach_us(callback(this, &RA8875::_TouchTicker), TOUCH_TICKER_uS);
WiredHome 150:35a4db3081c1 74 #else
WiredHome 150:35a4db3081c1 75 touchTicker.attach_us(this, &RA8875::_TouchTicker, TOUCH_TICKER_uS);
WiredHome 150:35a4db3081c1 76 #endif
WiredHome 193:74f80834d59d 77 #endif
WiredHome 165:695c24cc5197 78 timeSinceTouch.start();
WiredHome 165:695c24cc5197 79 timeSinceTouch.reset();
WiredHome 157:1565f38ca44b 80 r = _internal_ts_cal();
WiredHome 83:7bad0068cca0 81 }
WiredHome 157:1565f38ca44b 82 return r;
WiredHome 78:faf49c381591 83 }
WiredHome 78:faf49c381591 84
WiredHome 124:1690a7ae871c 85
WiredHome 124:1690a7ae871c 86 RetCode_t RA8875::TouchPanelInit(uint8_t bTpEnable, uint8_t bTpAutoManual, uint8_t bTpDebounce, uint8_t bTpManualMode, uint8_t bTpAdcClkDiv, uint8_t bTpAdcSampleTime)
WiredHome 124:1690a7ae871c 87 {
WiredHome 165:695c24cc5197 88 if (useTouchPanel == TP_GSL1680) {
WiredHome 165:695c24cc5197 89 INFO("TouchPanelInit: TP_GSL1680");
WiredHome 167:8aa3fb2a5a31 90 /// @todo Added support for TP_GSL1680
WiredHome 165:695c24cc5197 91 } else if (useTouchPanel == TP_FT5206) {
WiredHome 165:695c24cc5197 92 INFO("TouchPanelInit: TP_FT5206");
WiredHome 124:1690a7ae871c 93 TouchPanelInit();
WiredHome 124:1690a7ae871c 94 } else {
WiredHome 155:b3f225ae572c 95 INFO("TouchPanelInit: TP_RES");
WiredHome 124:1690a7ae871c 96 // Parameter bounds check
WiredHome 124:1690a7ae871c 97 if( \
WiredHome 124:1690a7ae871c 98 !(bTpEnable == TP_ENABLE || bTpEnable == TP_ENABLE) || \
WiredHome 124:1690a7ae871c 99 !(bTpAutoManual == TP_MODE_AUTO || bTpAutoManual == TP_MODE_MANUAL) || \
WiredHome 124:1690a7ae871c 100 !(bTpDebounce == TP_DEBOUNCE_OFF || bTpDebounce == TP_DEBOUNCE_ON) || \
WiredHome 124:1690a7ae871c 101 !(bTpManualMode <= TP_MANUAL_LATCH_Y) || \
WiredHome 124:1690a7ae871c 102 !(bTpAdcClkDiv <= TP_ADC_CLKDIV_128) || \
WiredHome 124:1690a7ae871c 103 !(bTpAdcSampleTime <= TP_ADC_SAMPLE_65536_CLKS) \
WiredHome 124:1690a7ae871c 104 ) return bad_parameter;
WiredHome 124:1690a7ae871c 105 // Construct the config byte for TPCR0 and write them
WiredHome 193:74f80834d59d 106 WriteCommand(RA8875_TPCR0, bTpEnable | bTpAdcClkDiv | bTpAdcSampleTime); // Note: Wakeup is never enabled
WiredHome 124:1690a7ae871c 107 // Construct the config byte for TPCR1 and write them
WiredHome 193:74f80834d59d 108 WriteCommand(RA8875_TPCR1, bTpDebounce | bTpManualMode); // Note: Always uses internal Vref.
WiredHome 124:1690a7ae871c 109 // Set up the interrupt flag and enable bits
WiredHome 193:74f80834d59d 110 WriteCommand(RA8875_INTC1, ReadCommand(RA8875_INTC1) | RA8875_INT_TP); // reg RA8875_INTC1: Enable Touch Panel Interrupts (D2 = 1)
WiredHome 193:74f80834d59d 111 WriteCommand(RA8875_INTC2, RA8875_INT_TP); // reg RA8875_INTC2: Clear any TP interrupt flag
WiredHome 124:1690a7ae871c 112 touchSample = 0;
WiredHome 124:1690a7ae871c 113 touchState = no_cal;
WiredHome 124:1690a7ae871c 114 if (bTpEnable == TP_ENABLE) {
WiredHome 150:35a4db3081c1 115 //touchTicker.attach_us(callback(this, &RA8875::_TouchTicker), TOUCH_TICKER_uS);
WiredHome 181:0032d1b8f5d4 116 #if (MBED_MAJOR_VERSION >= 5) || (MBED_LIBRARY_VERSION > 127)
WiredHome 145:5eb2492acdda 117 touchTicker.attach_us(callback(this, &RA8875::_TouchTicker), TOUCH_TICKER_uS);
WiredHome 150:35a4db3081c1 118 #else
WiredHome 150:35a4db3081c1 119 touchTicker.attach_us(this, &RA8875::_TouchTicker, TOUCH_TICKER_uS);
WiredHome 150:35a4db3081c1 120 #endif
WiredHome 150:35a4db3081c1 121
WiredHome 165:695c24cc5197 122 timeSinceTouch.start();
WiredHome 165:695c24cc5197 123 timeSinceTouch.reset();
WiredHome 124:1690a7ae871c 124 } else {
WiredHome 124:1690a7ae871c 125 touchTicker.detach();
WiredHome 165:695c24cc5197 126 timeSinceTouch.stop();
WiredHome 124:1690a7ae871c 127 }
WiredHome 157:1565f38ca44b 128 _internal_ts_cal();
WiredHome 124:1690a7ae871c 129 }
WiredHome 124:1690a7ae871c 130 return noerror;
WiredHome 124:1690a7ae871c 131 }
WiredHome 124:1690a7ae871c 132
WiredHome 124:1690a7ae871c 133
WiredHome 124:1690a7ae871c 134 int RA8875::TouchChannels(void)
WiredHome 124:1690a7ae871c 135 {
WiredHome 165:695c24cc5197 136 if (useTouchPanel == TP_GSL1680) {
WiredHome 176:4ab96d33a8ec 137 return GSL1680_TOUCH_POINTS; // based on TP_GSL1680 firmware
WiredHome 165:695c24cc5197 138 } else if (useTouchPanel == TP_FT5206) {
WiredHome 176:4ab96d33a8ec 139 return FT5206_TOUCH_POINTS; // based on the FT5206 hardware
WiredHome 124:1690a7ae871c 140 } else if (useTouchPanel == TP_RES) {
WiredHome 176:4ab96d33a8ec 141 return RESISTIVE_TOUCH_POINTS; // based on the RA8875 resistive touch driver
WiredHome 124:1690a7ae871c 142 } else {
WiredHome 124:1690a7ae871c 143 return 0; // it isn't enabled, so there are none.
WiredHome 124:1690a7ae871c 144 }
WiredHome 124:1690a7ae871c 145 }
WiredHome 124:1690a7ae871c 146
WiredHome 124:1690a7ae871c 147
WiredHome 124:1690a7ae871c 148 // +----------------------------------------------------+
WiredHome 124:1690a7ae871c 149 // | |
WiredHome 124:1690a7ae871c 150 // | 1 |
WiredHome 124:1690a7ae871c 151 // | |
WiredHome 124:1690a7ae871c 152 // | |
WiredHome 124:1690a7ae871c 153 // | 2 |
WiredHome 124:1690a7ae871c 154 // | |
WiredHome 124:1690a7ae871c 155 // | |
WiredHome 124:1690a7ae871c 156 // | 3 |
WiredHome 124:1690a7ae871c 157 // | |
WiredHome 124:1690a7ae871c 158 // +----------------------------------------------------+
WiredHome 81:01da2e34283d 159
WiredHome 81:01da2e34283d 160 RetCode_t RA8875::TouchPanelCalibrate(tpMatrix_t * matrix)
WiredHome 81:01da2e34283d 161 {
WiredHome 81:01da2e34283d 162 return TouchPanelCalibrate(NULL, matrix);
WiredHome 81:01da2e34283d 163 }
WiredHome 81:01da2e34283d 164
WiredHome 88:bfddef6ec836 165 RetCode_t RA8875::TouchPanelCalibrate(const char * msg, tpMatrix_t * matrix, int maxwait_s)
WiredHome 81:01da2e34283d 166 {
WiredHome 81:01da2e34283d 167 point_t pTest[3];
WiredHome 81:01da2e34283d 168 point_t pSample[3];
WiredHome 83:7bad0068cca0 169 int x,y;
WiredHome 88:bfddef6ec836 170 Timer timeout; // timeout guards for not-installed, stuck, user not present...
WiredHome 124:1690a7ae871c 171
WiredHome 88:bfddef6ec836 172 timeout.start();
WiredHome 123:2f45e80fec5f 173 while (TouchPanelA2DFiltered(&x, &y) && timeout.read() < maxwait_s) {
WiredHome 83:7bad0068cca0 174 wait_ms(20);
WiredHome 123:2f45e80fec5f 175 if (idle_callback) {
WiredHome 149:c62c4b2d6a15 176 if (external_abort == (*idle_callback)(touchcal_wait, 0)) {
WiredHome 123:2f45e80fec5f 177 return external_abort;
WiredHome 123:2f45e80fec5f 178 }
WiredHome 123:2f45e80fec5f 179 }
WiredHome 123:2f45e80fec5f 180 }
WiredHome 81:01da2e34283d 181 cls();
WiredHome 157:1565f38ca44b 182 if (msg) { // User defines the message
WiredHome 157:1565f38ca44b 183 if (*msg) puts(msg); // If any
WiredHome 157:1565f38ca44b 184 } else { // Default message
WiredHome 157:1565f38ca44b 185 puts("Touch '+' to calibrate the touch panel");
WiredHome 157:1565f38ca44b 186 }
WiredHome 81:01da2e34283d 187 SetTextCursor(0,height()/2);
WiredHome 124:1690a7ae871c 188 pTest[0].x = 50;
WiredHome 124:1690a7ae871c 189 pTest[0].y = 50;
WiredHome 124:1690a7ae871c 190 pTest[1].x = width() - 50;
WiredHome 124:1690a7ae871c 191 pTest[1].y = height()/2;
WiredHome 124:1690a7ae871c 192 pTest[2].x = width()/2;
WiredHome 124:1690a7ae871c 193 pTest[2].y = height() - 50;
WiredHome 88:bfddef6ec836 194
WiredHome 81:01da2e34283d 195 for (int i=0; i<3; i++) {
WiredHome 81:01da2e34283d 196 foreground(Blue);
WiredHome 81:01da2e34283d 197 printf(" (%3d,%3d) => ", pTest[i].x, pTest[i].y);
WiredHome 157:1565f38ca44b 198 fillcircle(pTest[i].x,pTest[i].y, 20, White);
WiredHome 157:1565f38ca44b 199 line(pTest[i].x-10, pTest[i].y, pTest[i].x+10, pTest[i].y, Blue);
WiredHome 157:1565f38ca44b 200 line(pTest[i].x, pTest[i].y-10, pTest[i].x, pTest[i].y+10, Blue);
WiredHome 123:2f45e80fec5f 201 while (!TouchPanelA2DFiltered(&x, &y) && timeout.read() < maxwait_s) {
WiredHome 81:01da2e34283d 202 wait_ms(20);
WiredHome 123:2f45e80fec5f 203 if (idle_callback) {
WiredHome 149:c62c4b2d6a15 204 if (external_abort == (*idle_callback)(touchcal_wait, 0)) {
WiredHome 123:2f45e80fec5f 205 return external_abort;
WiredHome 123:2f45e80fec5f 206 }
WiredHome 123:2f45e80fec5f 207 }
WiredHome 123:2f45e80fec5f 208 }
WiredHome 81:01da2e34283d 209 pSample[i].x = x;
WiredHome 81:01da2e34283d 210 pSample[i].y = y;
WiredHome 157:1565f38ca44b 211 fillcircle(pTest[i].x,pTest[i].y, 20, Black); // Erase the target
WiredHome 157:1565f38ca44b 212 //line(pTest[i].x-10, pTest[i].y, pTest[i].x+10, pTest[i].y, Black);
WiredHome 157:1565f38ca44b 213 //line(pTest[i].x, pTest[i].y-10, pTest[i].x, pTest[i].y+10, Black);
WiredHome 81:01da2e34283d 214 foreground(Blue);
WiredHome 81:01da2e34283d 215 printf(" (%4d,%4d)\r\n", x,y);
WiredHome 123:2f45e80fec5f 216 while (TouchPanelA2DFiltered(&x, &y) && timeout.read() < maxwait_s) {
WiredHome 81:01da2e34283d 217 wait_ms(20);
WiredHome 123:2f45e80fec5f 218 if (idle_callback) {
WiredHome 149:c62c4b2d6a15 219 if (external_abort == (*idle_callback)(touchcal_wait, 0)) {
WiredHome 123:2f45e80fec5f 220 return external_abort;
WiredHome 123:2f45e80fec5f 221 }
WiredHome 123:2f45e80fec5f 222 }
WiredHome 123:2f45e80fec5f 223 }
WiredHome 123:2f45e80fec5f 224 for (int t=0; t<100; t++) {
WiredHome 123:2f45e80fec5f 225 wait_ms(20);
WiredHome 123:2f45e80fec5f 226 if (idle_callback) {
WiredHome 149:c62c4b2d6a15 227 if (external_abort == (*idle_callback)(touchcal_wait, 0)) {
WiredHome 123:2f45e80fec5f 228 return external_abort;
WiredHome 123:2f45e80fec5f 229 }
WiredHome 123:2f45e80fec5f 230 }
WiredHome 123:2f45e80fec5f 231 }
WiredHome 81:01da2e34283d 232 }
WiredHome 88:bfddef6ec836 233 if (timeout.read() >= maxwait_s)
WiredHome 88:bfddef6ec836 234 return touch_cal_timeout;
WiredHome 88:bfddef6ec836 235 else
WiredHome 88:bfddef6ec836 236 return TouchPanelComputeCalibration(pTest, pSample, matrix);
WiredHome 81:01da2e34283d 237 }
WiredHome 81:01da2e34283d 238
WiredHome 81:01da2e34283d 239
WiredHome 81:01da2e34283d 240 /**********************************************************************
WiredHome 81:01da2e34283d 241 *
WiredHome 123:2f45e80fec5f 242 * Function: TouchPanelReadable()
WiredHome 81:01da2e34283d 243 *
WiredHome 81:01da2e34283d 244 * Description: Given a valid set of calibration factors and a point
WiredHome 81:01da2e34283d 245 * value reported by the touch screen, this function
WiredHome 81:01da2e34283d 246 * calculates and returns the true (or closest to true)
WiredHome 124:1690a7ae871c 247 * display point below the spot where the touch screen
WiredHome 81:01da2e34283d 248 * was touched.
WiredHome 124:1690a7ae871c 249 *
WiredHome 81:01da2e34283d 250 *
WiredHome 124:1690a7ae871c 251 *
WiredHome 81:01da2e34283d 252 * Argument(s): displayPtr (output) - Pointer to the calculated
WiredHome 81:01da2e34283d 253 * (true) display point.
WiredHome 81:01da2e34283d 254 * screenPtr (input) - Pointer to the reported touch
WiredHome 81:01da2e34283d 255 * screen point.
WiredHome 81:01da2e34283d 256 * matrixPtr (input) - Pointer to calibration factors
WiredHome 81:01da2e34283d 257 * matrix previously calculated
WiredHome 124:1690a7ae871c 258 * from a call to
WiredHome 81:01da2e34283d 259 * setCalibrationMatrix()
WiredHome 124:1690a7ae871c 260 *
WiredHome 81:01da2e34283d 261 *
WiredHome 124:1690a7ae871c 262 * The function simply solves for Xd and Yd by implementing the
WiredHome 124:1690a7ae871c 263 * computations required by the translation matrix.
WiredHome 124:1690a7ae871c 264 *
WiredHome 81:01da2e34283d 265 * /- -\
WiredHome 81:01da2e34283d 266 * /- -\ /- -\ | |
WiredHome 81:01da2e34283d 267 * | | | | | Xs |
WiredHome 81:01da2e34283d 268 * | Xd | | A B C | | |
WiredHome 81:01da2e34283d 269 * | | = | | * | Ys |
WiredHome 81:01da2e34283d 270 * | Yd | | D E F | | |
WiredHome 81:01da2e34283d 271 * | | | | | 1 |
WiredHome 81:01da2e34283d 272 * \- -/ \- -/ | |
WiredHome 81:01da2e34283d 273 * \- -/
WiredHome 124:1690a7ae871c 274 *
WiredHome 81:01da2e34283d 275 * It must be kept brief to avoid consuming CPU cycles.
WiredHome 81:01da2e34283d 276 *
WiredHome 124:1690a7ae871c 277 * Return: OK - the display point was correctly calculated
WiredHome 81:01da2e34283d 278 * and its value is in the output argument.
WiredHome 81:01da2e34283d 279 * NOT_OK - an error was detected and the function
WiredHome 81:01da2e34283d 280 * failed to return a valid point.
WiredHome 81:01da2e34283d 281 *
WiredHome 81:01da2e34283d 282 * NOTE! NOTE! NOTE!
WiredHome 81:01da2e34283d 283 *
WiredHome 81:01da2e34283d 284 * setCalibrationMatrix() and getDisplayPoint() will do fine
WiredHome 124:1690a7ae871c 285 * for you as they are, provided that your digitizer
WiredHome 81:01da2e34283d 286 * resolution does not exceed 10 bits (1024 values). Higher
WiredHome 81:01da2e34283d 287 * resolutions may cause the integer operations to overflow
WiredHome 124:1690a7ae871c 288 * and return incorrect values. If you wish to use these
WiredHome 124:1690a7ae871c 289 * functions with digitizer resolutions of 12 bits (4096
WiredHome 124:1690a7ae871c 290 * values) you will either have to a) use 64-bit signed
WiredHome 124:1690a7ae871c 291 * integer variables and math, or b) judiciously modify the
WiredHome 124:1690a7ae871c 292 * operations to scale results by a factor of 2 or even 4.
WiredHome 81:01da2e34283d 293 *
WiredHome 81:01da2e34283d 294 */
WiredHome 83:7bad0068cca0 295 TouchCode_t RA8875::TouchPanelReadable(point_t * TouchPoint)
WiredHome 81:01da2e34283d 296 {
WiredHome 124:1690a7ae871c 297 TouchCode_t ts = no_touch;
WiredHome 124:1690a7ae871c 298
WiredHome 165:695c24cc5197 299 if (useTouchPanel == TP_FT5206) {
WiredHome 193:74f80834d59d 300 INFO("TP_FT5206");
WiredHome 165:695c24cc5197 301 } else if (useTouchPanel == TP_GSL1680) {
WiredHome 193:74f80834d59d 302 INFO("TP_GSL1680");
WiredHome 165:695c24cc5197 303 } else if (useTouchPanel == TP_RES) {
WiredHome 124:1690a7ae871c 304 int a2dX = 0;
WiredHome 124:1690a7ae871c 305 int a2dY = 0;
WiredHome 190:3132b7dfad82 306
WiredHome 124:1690a7ae871c 307 touchInfo[0].touchID = 0;
WiredHome 124:1690a7ae871c 308 ts = TouchPanelA2DFiltered(&a2dX, &a2dY);
WiredHome 193:74f80834d59d 309 #ifdef DEBUG
WiredHome 193:74f80834d59d 310 static TouchCode_t tsLast;
WiredHome 193:74f80834d59d 311 if (tsLast != ts)
WiredHome 193:74f80834d59d 312 INFO("ts: %d", ts);
WiredHome 193:74f80834d59d 313 tsLast = ts;
WiredHome 193:74f80834d59d 314 #endif
WiredHome 124:1690a7ae871c 315 if (ts != no_touch) {
WiredHome 124:1690a7ae871c 316 panelTouched = true;
WiredHome 124:1690a7ae871c 317 numberOfTouchPoints = 1;
WiredHome 124:1690a7ae871c 318
WiredHome 124:1690a7ae871c 319 if (tpMatrix.Divider != 0) {
WiredHome 103:7e0464ca6c5c 320 /* Operation order is important since we are doing integer */
WiredHome 103:7e0464ca6c5c 321 /* math. Make sure you add all terms together before */
WiredHome 103:7e0464ca6c5c 322 /* dividing, so that the remainder is not rounded off */
WiredHome 103:7e0464ca6c5c 323 /* prematurely. */
WiredHome 124:1690a7ae871c 324 touchInfo[0].coordinates.x = ( (tpMatrix.An * a2dX) +
WiredHome 127:db7f2c704693 325 (tpMatrix.Bn * a2dY) + tpMatrix.Cn
WiredHome 103:7e0464ca6c5c 326 ) / tpMatrix.Divider ;
WiredHome 124:1690a7ae871c 327 touchInfo[0].coordinates.y = ( (tpMatrix.Dn * a2dX) +
WiredHome 127:db7f2c704693 328 (tpMatrix.En * a2dY) + tpMatrix.Fn
WiredHome 103:7e0464ca6c5c 329 ) / tpMatrix.Divider ;
WiredHome 124:1690a7ae871c 330 } else {
WiredHome 124:1690a7ae871c 331 ts = no_cal;
WiredHome 103:7e0464ca6c5c 332 }
WiredHome 81:01da2e34283d 333 } else {
WiredHome 124:1690a7ae871c 334 numberOfTouchPoints = 0;
WiredHome 81:01da2e34283d 335 }
WiredHome 124:1690a7ae871c 336 touchInfo[0].touchCode = ts;
WiredHome 124:1690a7ae871c 337 }
WiredHome 165:695c24cc5197 338 // For Resistive touch, panelTouched is computed above.
WiredHome 165:695c24cc5197 339 // For Cap Sense, panelTouched is set in another process
WiredHome 124:1690a7ae871c 340 if (panelTouched == true) {
WiredHome 124:1690a7ae871c 341 panelTouched = false;
WiredHome 124:1690a7ae871c 342 if (TouchPoint) {
WiredHome 181:0032d1b8f5d4 343 *TouchPoint = TranslateOrientation(touchInfo[0].coordinates);
WiredHome 124:1690a7ae871c 344 ts = touchInfo[0].touchCode;
WiredHome 193:74f80834d59d 345 #ifdef DEBUG
WiredHome 193:74f80834d59d 346 static TouchCode_t lastTS = no_touch;
WiredHome 193:74f80834d59d 347 if (lastTS != ts)
WiredHome 155:b3f225ae572c 348 INFO("Touch[0] %2d (%4d,%4d)", touchInfo[0].touchCode,
WiredHome 155:b3f225ae572c 349 touchInfo[0].coordinates.x, touchInfo[0].coordinates.y);
WiredHome 193:74f80834d59d 350 lastTS = ts;
WiredHome 193:74f80834d59d 351 #endif
WiredHome 130:d633e80840e0 352 } else {
WiredHome 130:d633e80840e0 353 ts = touch;
WiredHome 124:1690a7ae871c 354 }
WiredHome 81:01da2e34283d 355 }
WiredHome 83:7bad0068cca0 356 return ts;
WiredHome 81:01da2e34283d 357 }
WiredHome 81:01da2e34283d 358
WiredHome 190:3132b7dfad82 359 uint8_t RA8875::TouchID(uint8_t channel)
WiredHome 166:53fd4a876dac 360 {
WiredHome 166:53fd4a876dac 361 if (channel >= TouchChannels())
WiredHome 166:53fd4a876dac 362 channel = 0;
WiredHome 190:3132b7dfad82 363 return touchInfo[channel].touchID;
WiredHome 166:53fd4a876dac 364 }
WiredHome 166:53fd4a876dac 365
WiredHome 190:3132b7dfad82 366 TouchCode_t RA8875::TouchCode(uint8_t channel)
WiredHome 190:3132b7dfad82 367 {
WiredHome 166:53fd4a876dac 368 if (channel >= TouchChannels())
WiredHome 166:53fd4a876dac 369 channel = 0;
WiredHome 181:0032d1b8f5d4 370 INFO("TouchCode[%d] = %d", channel, touchInfo[channel].touchCode);
WiredHome 181:0032d1b8f5d4 371 return touchInfo[channel].touchCode;
WiredHome 166:53fd4a876dac 372 }
WiredHome 166:53fd4a876dac 373
WiredHome 166:53fd4a876dac 374 point_t RA8875::TouchCoordinates(uint8_t channel)
WiredHome 166:53fd4a876dac 375 {
WiredHome 166:53fd4a876dac 376 if (channel >= TouchChannels())
WiredHome 166:53fd4a876dac 377 channel = 0;
WiredHome 190:3132b7dfad82 378 return TranslateOrientation(touchInfo[channel].coordinates);
WiredHome 166:53fd4a876dac 379 }
WiredHome 81:01da2e34283d 380
WiredHome 85:022bba13c5c4 381 TouchCode_t RA8875::TouchPanelGet(point_t * TouchPoint)
WiredHome 85:022bba13c5c4 382 {
WiredHome 123:2f45e80fec5f 383 TouchCode_t t = no_touch;
WiredHome 124:1690a7ae871c 384
WiredHome 123:2f45e80fec5f 385 while (true) {
WiredHome 85:022bba13c5c4 386 t = TouchPanelReadable(TouchPoint);
WiredHome 123:2f45e80fec5f 387 if (t != no_touch)
WiredHome 123:2f45e80fec5f 388 break;
WiredHome 123:2f45e80fec5f 389 if (idle_callback) {
WiredHome 149:c62c4b2d6a15 390 if (external_abort == (*idle_callback)(touch_wait, 0)) {
WiredHome 123:2f45e80fec5f 391 return no_touch;
WiredHome 123:2f45e80fec5f 392 }
WiredHome 123:2f45e80fec5f 393 }
WiredHome 123:2f45e80fec5f 394 }
WiredHome 85:022bba13c5c4 395 return t;
WiredHome 85:022bba13c5c4 396 }
WiredHome 85:022bba13c5c4 397
WiredHome 181:0032d1b8f5d4 398 point_t RA8875::TranslateOrientation(point_t rawPoint)
WiredHome 181:0032d1b8f5d4 399 {
WiredHome 181:0032d1b8f5d4 400 point_t newPoint = rawPoint;
WiredHome 190:3132b7dfad82 401
WiredHome 184:464cc376265d 402 #if 1
WiredHome 181:0032d1b8f5d4 403 switch (screen_orientation) {
WiredHome 181:0032d1b8f5d4 404 default:
WiredHome 181:0032d1b8f5d4 405 case rotate_0:
WiredHome 181:0032d1b8f5d4 406 newPoint = rawPoint;
WiredHome 181:0032d1b8f5d4 407 break;
WiredHome 181:0032d1b8f5d4 408 case rotate_90:
WiredHome 181:0032d1b8f5d4 409 newPoint.x = rawPoint.y;
WiredHome 181:0032d1b8f5d4 410 newPoint.y = height() - rawPoint.x;
WiredHome 181:0032d1b8f5d4 411 break;
WiredHome 181:0032d1b8f5d4 412 case rotate_180:
WiredHome 181:0032d1b8f5d4 413 newPoint.x = width() - rawPoint.x;
WiredHome 181:0032d1b8f5d4 414 newPoint.y = height() - rawPoint.y;
WiredHome 181:0032d1b8f5d4 415 break;
WiredHome 181:0032d1b8f5d4 416 case rotate_270:
WiredHome 181:0032d1b8f5d4 417 newPoint.x = height() - rawPoint.y;
WiredHome 181:0032d1b8f5d4 418 newPoint.y = rawPoint.x;
WiredHome 181:0032d1b8f5d4 419 break;
WiredHome 181:0032d1b8f5d4 420 }
WiredHome 193:74f80834d59d 421 //INFO("Translate(%3d x %3d) => (%3d x %3d)", rawPoint.x, rawPoint.y, newPoint.x, newPoint.y);
WiredHome 181:0032d1b8f5d4 422 #endif
WiredHome 181:0032d1b8f5d4 423 return newPoint;
WiredHome 181:0032d1b8f5d4 424 }
WiredHome 181:0032d1b8f5d4 425
WiredHome 181:0032d1b8f5d4 426
WiredHome 123:2f45e80fec5f 427 // Below here are primarily "helper" functions. While many are accessible
WiredHome 123:2f45e80fec5f 428 // to the user code, they usually don't need to be called.
WiredHome 123:2f45e80fec5f 429
WiredHome 81:01da2e34283d 430 RetCode_t RA8875::TouchPanelSetMatrix(tpMatrix_t * matrixPtr)
WiredHome 81:01da2e34283d 431 {
WiredHome 81:01da2e34283d 432 if (matrixPtr == NULL || matrixPtr->Divider == 0)
WiredHome 81:01da2e34283d 433 return bad_parameter;
WiredHome 81:01da2e34283d 434 memcpy(&tpMatrix, matrixPtr, sizeof(tpMatrix_t));
WiredHome 83:7bad0068cca0 435 touchState = no_touch;
WiredHome 81:01da2e34283d 436 return noerror;
WiredHome 81:01da2e34283d 437 }
WiredHome 81:01da2e34283d 438
WiredHome 157:1565f38ca44b 439 const tpMatrix_t * RA8875::TouchPanelGetMatrix()
WiredHome 157:1565f38ca44b 440 {
WiredHome 157:1565f38ca44b 441 return &tpMatrix;
WiredHome 157:1565f38ca44b 442 }
WiredHome 157:1565f38ca44b 443
WiredHome 157:1565f38ca44b 444
WiredHome 83:7bad0068cca0 445 static void InsertionSort(int * buf, int bufsize)
WiredHome 83:7bad0068cca0 446 {
WiredHome 83:7bad0068cca0 447 int i, j;
WiredHome 83:7bad0068cca0 448 int temp;
WiredHome 124:1690a7ae871c 449
WiredHome 108:7415c405ee08 450 for(i = 1; i < bufsize; i++) {
WiredHome 83:7bad0068cca0 451 temp = buf[i];
WiredHome 83:7bad0068cca0 452 j = i;
WiredHome 83:7bad0068cca0 453 while( j && (buf[j-1] > temp) ) {
WiredHome 83:7bad0068cca0 454 buf[j] = buf[j-1];
WiredHome 83:7bad0068cca0 455 j = j-1;
WiredHome 83:7bad0068cca0 456 }
WiredHome 83:7bad0068cca0 457 buf[j] = temp;
WiredHome 83:7bad0068cca0 458 } // End of sort
WiredHome 83:7bad0068cca0 459 }
WiredHome 83:7bad0068cca0 460
WiredHome 83:7bad0068cca0 461
WiredHome 83:7bad0068cca0 462 void RA8875::_TouchTicker(void)
WiredHome 78:faf49c381591 463 {
WiredHome 155:b3f225ae572c 464 INFO("_TouchTicker()");
WiredHome 165:695c24cc5197 465 if (timeSinceTouch.read_us() > NOTOUCH_TIMEOUT_uS) {
WiredHome 83:7bad0068cca0 466 touchSample = 0;
WiredHome 193:74f80834d59d 467 if (touchState == held) {
WiredHome 83:7bad0068cca0 468 touchState = release;
WiredHome 193:74f80834d59d 469 INFO("release %d", touchState);
WiredHome 193:74f80834d59d 470 } else {
WiredHome 193:74f80834d59d 471 INFO("!= held %d", touchState);
WiredHome 83:7bad0068cca0 472 touchState = no_touch;
WiredHome 193:74f80834d59d 473 }
WiredHome 165:695c24cc5197 474 timeSinceTouch.reset();
WiredHome 83:7bad0068cca0 475 }
WiredHome 83:7bad0068cca0 476 }
WiredHome 83:7bad0068cca0 477
WiredHome 83:7bad0068cca0 478 TouchCode_t RA8875::TouchPanelA2DRaw(int *x, int *y)
WiredHome 83:7bad0068cca0 479 {
WiredHome 154:ad2450fc3dc3 480 INFO("A2Raw");
WiredHome 193:74f80834d59d 481 if( (ReadCommand(RA8875_INTC2) & RA8875_INT_TP) ) { // Test for TP Interrupt pending in register RA8875_INTC2
WiredHome 154:ad2450fc3dc3 482 INFO("Int pending");
WiredHome 165:695c24cc5197 483 timeSinceTouch.reset();
WiredHome 193:74f80834d59d 484 *y = ReadCommand(RA8875_TPYH) << 2 | ( (ReadCommand(RA8875_TPXYL) & 0xC) >> 2 ); // D[9:2] from reg RA8875_TPYH, D[1:0] from reg RA8875_TPXYL[3:2]
WiredHome 193:74f80834d59d 485 *x = ReadCommand(RA8875_TPXH) << 2 | ( (ReadCommand(RA8875_TPXYL) & 0x3) ); // D[9:2] from reg RA8875_TPXH, D[1:0] from reg RA8875_TPXYL[1:0]
WiredHome 193:74f80834d59d 486 INFO("(x,y) = (%d,%d)", *x, *y);
WiredHome 193:74f80834d59d 487 WriteCommand(RA8875_INTC2, RA8875_INT_TP); // reg RA8875_INTC2: Clear that TP interrupt flag
WiredHome 83:7bad0068cca0 488 touchState = touch;
WiredHome 193:74f80834d59d 489 } else if (ReadCommand(RA8875_TPXYL) & RA8875_TPXYL_ADET) {
WiredHome 193:74f80834d59d 490 INFO("held");
WiredHome 193:74f80834d59d 491 touchState = held;
WiredHome 83:7bad0068cca0 492 } else {
WiredHome 154:ad2450fc3dc3 493 INFO("no touch");
WiredHome 83:7bad0068cca0 494 touchState = no_touch;
WiredHome 83:7bad0068cca0 495 }
WiredHome 83:7bad0068cca0 496 return touchState;
WiredHome 83:7bad0068cca0 497 }
WiredHome 83:7bad0068cca0 498
WiredHome 83:7bad0068cca0 499 TouchCode_t RA8875::TouchPanelA2DFiltered(int *x, int *y)
WiredHome 83:7bad0068cca0 500 {
WiredHome 83:7bad0068cca0 501 static int xbuf[TPBUFSIZE], ybuf[TPBUFSIZE];
WiredHome 83:7bad0068cca0 502 static int lastX, lastY;
WiredHome 83:7bad0068cca0 503 int i, j;
WiredHome 83:7bad0068cca0 504 TouchCode_t ret = touchState;
WiredHome 78:faf49c381591 505
WiredHome 193:74f80834d59d 506 if ( (ReadCommand(RA8875_INTC2) & RA8875_INT_TP) ) { // Test for TP Interrupt pending in register RA8875_INTC2
WiredHome 165:695c24cc5197 507 timeSinceTouch.reset();
WiredHome 78:faf49c381591 508 // Get the next data samples
WiredHome 193:74f80834d59d 509 ybuf[touchSample] = ReadCommand(RA8875_TPYH) << 2 | ( (ReadCommand(RA8875_TPXYL) & 0xC) >> 2 ); // D[9:2] from reg RA8875_TPYH, D[1:0] from reg RA8875_TPXYL[3:2]
WiredHome 193:74f80834d59d 510 xbuf[touchSample] = ReadCommand(RA8875_TPXH) << 2 | ( (ReadCommand(RA8875_TPXYL) & 0x3) ); // D[9:2] from reg RA8875_TPXH, D[1:0] from reg RA8875_TPXYL[1:0]
WiredHome 78:faf49c381591 511 // Check for a complete set
WiredHome 83:7bad0068cca0 512 if(++touchSample == TPBUFSIZE) {
WiredHome 78:faf49c381591 513 // Buffers are full, so process them using Finn's method described in Analog Dialogue No. 44, Feb 2010
WiredHome 78:faf49c381591 514 // This requires sorting the samples in order of size, then discarding the top 25% and
WiredHome 78:faf49c381591 515 // bottom 25% as noise spikes. Finally, the middle 50% of the values are averaged to
WiredHome 78:faf49c381591 516 // reduce Gaussian noise.
WiredHome 83:7bad0068cca0 517 InsertionSort(ybuf, TPBUFSIZE);
WiredHome 83:7bad0068cca0 518 InsertionSort(xbuf, TPBUFSIZE);
WiredHome 78:faf49c381591 519 // Average the middle half of the Y values and report them
WiredHome 78:faf49c381591 520 j = 0;
WiredHome 78:faf49c381591 521 for(i = (TPBUFSIZE/4) - 1; i < TPBUFSIZE - TPBUFSIZE/4; i++ ) {
WiredHome 78:faf49c381591 522 j += ybuf[i];
WiredHome 78:faf49c381591 523 }
WiredHome 83:7bad0068cca0 524 *y = lastY = j * (float)2/TPBUFSIZE; // This is the average
WiredHome 78:faf49c381591 525 // Average the middle half of the X values and report them
WiredHome 78:faf49c381591 526 j = 0;
WiredHome 78:faf49c381591 527 for(i = (TPBUFSIZE/4) - 1; i < TPBUFSIZE - TPBUFSIZE/4; i++ ) {
WiredHome 78:faf49c381591 528 j += xbuf[i];
WiredHome 78:faf49c381591 529 }
WiredHome 83:7bad0068cca0 530 *x = lastX = j * (float)2/TPBUFSIZE; // This is the average
WiredHome 78:faf49c381591 531 // Tidy up and return
WiredHome 193:74f80834d59d 532 if (touchState == touch || touchState == held) {
WiredHome 83:7bad0068cca0 533 touchState = held;
WiredHome 193:74f80834d59d 534 INFO("held");
WiredHome 193:74f80834d59d 535 } else {
WiredHome 83:7bad0068cca0 536 touchState = touch;
WiredHome 193:74f80834d59d 537 INFO("touch");
WiredHome 193:74f80834d59d 538 }
WiredHome 83:7bad0068cca0 539 ret = touchState;
WiredHome 83:7bad0068cca0 540 touchSample = 0; // Ready to start on the next set of data samples
WiredHome 78:faf49c381591 541 } else {
WiredHome 78:faf49c381591 542 // Buffer not yet full, so do not return any results yet
WiredHome 83:7bad0068cca0 543 if (touchState == touch || touchState == held) {
WiredHome 83:7bad0068cca0 544 *x = lastX;
WiredHome 83:7bad0068cca0 545 *y = lastY;
WiredHome 193:74f80834d59d 546 {
WiredHome 193:74f80834d59d 547 static TouchCode_t lastTC = no_touch;
WiredHome 193:74f80834d59d 548 if (lastTC != touchState)
WiredHome 193:74f80834d59d 549 INFO("held");
WiredHome 193:74f80834d59d 550 lastTC = touchState;
WiredHome 193:74f80834d59d 551 }
WiredHome 83:7bad0068cca0 552 ret = touchState = held;
WiredHome 193:74f80834d59d 553 } else {
WiredHome 193:74f80834d59d 554 INFO("else %d, %d", touchState, touchSample);
WiredHome 83:7bad0068cca0 555 }
WiredHome 78:faf49c381591 556 }
WiredHome 193:74f80834d59d 557 WriteCommand(RA8875_INTC2, RA8875_INT_TP); // reg RA8875_INTC2: Clear that TP interrupt flag
WiredHome 193:74f80834d59d 558 } else if (0 == (ReadCommand(RA8875_TPXYL) & RA8875_TPXYL_ADET)) {
WiredHome 193:74f80834d59d 559 INFO("held");
WiredHome 193:74f80834d59d 560 *x = lastX;
WiredHome 193:74f80834d59d 561 *y = lastY;
WiredHome 193:74f80834d59d 562 ret = touchState = held;
WiredHome 193:74f80834d59d 563 } else if (timeSinceTouch.read_ms() < 20) {
WiredHome 193:74f80834d59d 564 *x = lastX;
WiredHome 193:74f80834d59d 565 *y = lastY;
WiredHome 193:74f80834d59d 566 //ret = touchState;
WiredHome 193:74f80834d59d 567 } else {
WiredHome 193:74f80834d59d 568 //INFO("touchState %d", touchState);
WiredHome 193:74f80834d59d 569 //touchSample = 0;
WiredHome 193:74f80834d59d 570 *x = lastX;
WiredHome 193:74f80834d59d 571 *y = lastY;
WiredHome 193:74f80834d59d 572 if (touchState == no_touch || touchState == release) {
WiredHome 193:74f80834d59d 573 ret = touchState = no_touch;
WiredHome 193:74f80834d59d 574 } else {
WiredHome 193:74f80834d59d 575 INFO("release");
WiredHome 193:74f80834d59d 576 touchSample = 0;
WiredHome 193:74f80834d59d 577 touchState = no_touch;
WiredHome 193:74f80834d59d 578 ret = release;
WiredHome 193:74f80834d59d 579 }
WiredHome 193:74f80834d59d 580 #if 0
WiredHome 83:7bad0068cca0 581 if (touchState == touch || touchState == held) {
WiredHome 83:7bad0068cca0 582 *x = lastX;
WiredHome 83:7bad0068cca0 583 *y = lastY;
WiredHome 83:7bad0068cca0 584 ret = touchState = held;
WiredHome 193:74f80834d59d 585 INFO("held");
WiredHome 83:7bad0068cca0 586 } else if (touchState == release) {
WiredHome 83:7bad0068cca0 587 *x = lastX;
WiredHome 83:7bad0068cca0 588 *y = lastY;
WiredHome 83:7bad0068cca0 589 ret = release;
WiredHome 83:7bad0068cca0 590 touchState = no_touch;
WiredHome 193:74f80834d59d 591 INFO("release");
WiredHome 83:7bad0068cca0 592 }
WiredHome 193:74f80834d59d 593 #endif
WiredHome 83:7bad0068cca0 594 }
WiredHome 83:7bad0068cca0 595 return ret;
WiredHome 78:faf49c381591 596 }
WiredHome 78:faf49c381591 597
WiredHome 167:8aa3fb2a5a31 598 /// The following section is derived from Carlos E. Vidales.
WiredHome 167:8aa3fb2a5a31 599 ///
WiredHome 167:8aa3fb2a5a31 600 /// @copyright &copy; 2001, Carlos E. Vidales. All rights reserved.
WiredHome 167:8aa3fb2a5a31 601 ///
WiredHome 167:8aa3fb2a5a31 602 /// This sample program was written and put in the public domain
WiredHome 167:8aa3fb2a5a31 603 /// by Carlos E. Vidales. The program is provided "as is"
WiredHome 167:8aa3fb2a5a31 604 /// without warranty of any kind, either expressed or implied.
WiredHome 167:8aa3fb2a5a31 605 /// If you choose to use the program within your own products
WiredHome 167:8aa3fb2a5a31 606 /// you do so at your own risk, and assume the responsibility
WiredHome 167:8aa3fb2a5a31 607 /// for servicing, repairing or correcting the program should
WiredHome 167:8aa3fb2a5a31 608 /// it prove defective in any manner.
WiredHome 167:8aa3fb2a5a31 609 /// You may copy and distribute the program's source code in any
WiredHome 167:8aa3fb2a5a31 610 /// medium, provided that you also include in each copy an
WiredHome 167:8aa3fb2a5a31 611 /// appropriate copyright notice and disclaimer of warranty.
WiredHome 167:8aa3fb2a5a31 612 /// You may also modify this program and distribute copies of
WiredHome 167:8aa3fb2a5a31 613 /// it provided that you include prominent notices stating
WiredHome 167:8aa3fb2a5a31 614 /// that you changed the file(s) and the date of any change,
WiredHome 167:8aa3fb2a5a31 615 /// and that you do not charge any royalties or licenses for
WiredHome 167:8aa3fb2a5a31 616 /// its use.
WiredHome 167:8aa3fb2a5a31 617 ///
WiredHome 167:8aa3fb2a5a31 618 /// This file contains functions that implement calculations
WiredHome 167:8aa3fb2a5a31 619 /// necessary to obtain calibration factors for a touch screen
WiredHome 167:8aa3fb2a5a31 620 /// that suffers from multiple distortion effects: namely,
WiredHome 167:8aa3fb2a5a31 621 /// translation, scaling and rotation.
WiredHome 167:8aa3fb2a5a31 622 ///
WiredHome 167:8aa3fb2a5a31 623 /// The following set of equations represent a valid display
WiredHome 167:8aa3fb2a5a31 624 /// point given a corresponding set of touch screen points:
WiredHome 167:8aa3fb2a5a31 625 ///
WiredHome 167:8aa3fb2a5a31 626 /// <pre>
WiredHome 190:3132b7dfad82 627 /// /- -\ //
WiredHome 190:3132b7dfad82 628 /// /- -\ /- -\ | | //
WiredHome 190:3132b7dfad82 629 /// | | | | | Xs | //
WiredHome 190:3132b7dfad82 630 /// | Xd | | A B C | | | //
WiredHome 190:3132b7dfad82 631 /// | | = | | * | Ys | //
WiredHome 190:3132b7dfad82 632 /// | Yd | | D E F | | | //
WiredHome 190:3132b7dfad82 633 /// | | | | | 1 | //
WiredHome 190:3132b7dfad82 634 /// \- -/ \- -/ | | //
WiredHome 190:3132b7dfad82 635 /// \- -/ //
WiredHome 167:8aa3fb2a5a31 636 /// where:
WiredHome 167:8aa3fb2a5a31 637 /// (Xd,Yd) represents the desired display point
WiredHome 167:8aa3fb2a5a31 638 /// coordinates,
WiredHome 167:8aa3fb2a5a31 639 /// (Xs,Ys) represents the available touch screen
WiredHome 167:8aa3fb2a5a31 640 /// coordinates, and the matrix
WiredHome 190:3132b7dfad82 641 /// /- -\ represents the factors used to translate
WiredHome 190:3132b7dfad82 642 /// |A,B,C| the available touch screen point values
WiredHome 190:3132b7dfad82 643 /// |D,E,F| into the corresponding display
WiredHome 190:3132b7dfad82 644 /// \- -/ coordinates.
WiredHome 190:3132b7dfad82 645 ///
WiredHome 167:8aa3fb2a5a31 646 /// Note that for practical considerations, the utilities
WiredHome 167:8aa3fb2a5a31 647 /// within this file do not use the matrix coefficients as
WiredHome 167:8aa3fb2a5a31 648 /// defined above, but instead use the following
WiredHome 167:8aa3fb2a5a31 649 /// equivalents, since floating point math is not used:
WiredHome 167:8aa3fb2a5a31 650 /// A = An/Divider
WiredHome 167:8aa3fb2a5a31 651 /// B = Bn/Divider
WiredHome 167:8aa3fb2a5a31 652 /// C = Cn/Divider
WiredHome 167:8aa3fb2a5a31 653 /// D = Dn/Divider
WiredHome 167:8aa3fb2a5a31 654 /// E = En/Divider
WiredHome 167:8aa3fb2a5a31 655 /// F = Fn/Divider
WiredHome 167:8aa3fb2a5a31 656 /// The functions provided within this file are:
WiredHome 167:8aa3fb2a5a31 657 /// setCalibrationMatrix() - calculates the set of factors
WiredHome 167:8aa3fb2a5a31 658 /// in the above equation, given
WiredHome 167:8aa3fb2a5a31 659 /// three sets of test points.
WiredHome 167:8aa3fb2a5a31 660 /// getDisplayPoint() - returns the actual display
WiredHome 167:8aa3fb2a5a31 661 /// coordinates, given a set of
WiredHome 167:8aa3fb2a5a31 662 /// touch screen coordinates.
WiredHome 167:8aa3fb2a5a31 663 /// translateRawScreenCoordinates() - helper function to transform
WiredHome 167:8aa3fb2a5a31 664 /// raw screen points into values
WiredHome 167:8aa3fb2a5a31 665 /// scaled to the desired display
WiredHome 167:8aa3fb2a5a31 666 /// resolution.
WiredHome 167:8aa3fb2a5a31 667 ///
WiredHome 167:8aa3fb2a5a31 668 ///
WiredHome 167:8aa3fb2a5a31 669 /// Function: setCalibrationMatrix()
WiredHome 167:8aa3fb2a5a31 670 ///
WiredHome 167:8aa3fb2a5a31 671 /// Description: Calling this function with valid input data
WiredHome 167:8aa3fb2a5a31 672 /// in the display and screen input arguments
WiredHome 167:8aa3fb2a5a31 673 /// causes the calibration factors between the
WiredHome 167:8aa3fb2a5a31 674 /// screen and display points to be calculated,
WiredHome 167:8aa3fb2a5a31 675 /// and the output argument - matrixPtr - to be
WiredHome 167:8aa3fb2a5a31 676 /// populated.
WiredHome 167:8aa3fb2a5a31 677 ///
WiredHome 167:8aa3fb2a5a31 678 /// This function needs to be called only when new
WiredHome 167:8aa3fb2a5a31 679 /// calibration factors are desired.
WiredHome 167:8aa3fb2a5a31 680 ///
WiredHome 167:8aa3fb2a5a31 681 ///
WiredHome 167:8aa3fb2a5a31 682 /// Argument(s): displayPtr (input) - Pointer to an array of three
WiredHome 167:8aa3fb2a5a31 683 /// sample, reference points.
WiredHome 167:8aa3fb2a5a31 684 /// screenPtr (input) - Pointer to the array of touch
WiredHome 167:8aa3fb2a5a31 685 /// screen points corresponding
WiredHome 167:8aa3fb2a5a31 686 /// to the reference display points.
WiredHome 167:8aa3fb2a5a31 687 /// matrixPtr (output) - Pointer to the calibration
WiredHome 167:8aa3fb2a5a31 688 /// matrix computed for the set
WiredHome 167:8aa3fb2a5a31 689 /// of points being provided.
WiredHome 167:8aa3fb2a5a31 690 ///
WiredHome 167:8aa3fb2a5a31 691 ///
WiredHome 167:8aa3fb2a5a31 692 /// From the article text, recall that the matrix coefficients are
WiredHome 167:8aa3fb2a5a31 693 /// resolved to be the following:
WiredHome 167:8aa3fb2a5a31 694 ///
WiredHome 167:8aa3fb2a5a31 695 ///
WiredHome 167:8aa3fb2a5a31 696 /// Divider = (Xs0 - Xs2)*(Ys1 - Ys2) - (Xs1 - Xs2)*(Ys0 - Ys2)
WiredHome 167:8aa3fb2a5a31 697 ///
WiredHome 167:8aa3fb2a5a31 698 ///
WiredHome 167:8aa3fb2a5a31 699 ///
WiredHome 167:8aa3fb2a5a31 700 /// (Xd0 - Xd2)*(Ys1 - Ys2) - (Xd1 - Xd2)*(Ys0 - Ys2)
WiredHome 167:8aa3fb2a5a31 701 /// A = ---------------------------------------------------
WiredHome 167:8aa3fb2a5a31 702 /// Divider
WiredHome 167:8aa3fb2a5a31 703 ///
WiredHome 167:8aa3fb2a5a31 704 ///
WiredHome 167:8aa3fb2a5a31 705 /// (Xs0 - Xs2)*(Xd1 - Xd2) - (Xd0 - Xd2)*(Xs1 - Xs2)
WiredHome 167:8aa3fb2a5a31 706 /// B = ---------------------------------------------------
WiredHome 167:8aa3fb2a5a31 707 /// Divider
WiredHome 167:8aa3fb2a5a31 708 ///
WiredHome 167:8aa3fb2a5a31 709 ///
WiredHome 167:8aa3fb2a5a31 710 /// Ys0*(Xs2*Xd1 - Xs1*Xd2) +
WiredHome 167:8aa3fb2a5a31 711 /// Ys1*(Xs0*Xd2 - Xs2*Xd0) +
WiredHome 167:8aa3fb2a5a31 712 /// Ys2*(Xs1*Xd0 - Xs0*Xd1)
WiredHome 167:8aa3fb2a5a31 713 /// C = ---------------------------------------------------
WiredHome 167:8aa3fb2a5a31 714 /// Divider
WiredHome 167:8aa3fb2a5a31 715 ///
WiredHome 167:8aa3fb2a5a31 716 ///
WiredHome 167:8aa3fb2a5a31 717 /// (Yd0 - Yd2)*(Ys1 - Ys2) - (Yd1 - Yd2)*(Ys0 - Ys2)
WiredHome 167:8aa3fb2a5a31 718 /// D = ---------------------------------------------------
WiredHome 167:8aa3fb2a5a31 719 /// Divider
WiredHome 167:8aa3fb2a5a31 720 ///
WiredHome 167:8aa3fb2a5a31 721 ///
WiredHome 167:8aa3fb2a5a31 722 /// (Xs0 - Xs2)*(Yd1 - Yd2) - (Yd0 - Yd2)*(Xs1 - Xs2)
WiredHome 167:8aa3fb2a5a31 723 /// E = ---------------------------------------------------
WiredHome 167:8aa3fb2a5a31 724 /// Divider
WiredHome 167:8aa3fb2a5a31 725 ///
WiredHome 167:8aa3fb2a5a31 726 ///
WiredHome 167:8aa3fb2a5a31 727 /// Ys0*(Xs2*Yd1 - Xs1*Yd2) +
WiredHome 167:8aa3fb2a5a31 728 /// Ys1*(Xs0*Yd2 - Xs2*Yd0) +
WiredHome 167:8aa3fb2a5a31 729 /// Ys2*(Xs1*Yd0 - Xs0*Yd1)
WiredHome 167:8aa3fb2a5a31 730 /// F = ---------------------------------------------------
WiredHome 167:8aa3fb2a5a31 731 /// Divider
WiredHome 167:8aa3fb2a5a31 732 ///
WiredHome 167:8aa3fb2a5a31 733 ///
WiredHome 167:8aa3fb2a5a31 734 /// Return: OK - the calibration matrix was correctly
WiredHome 167:8aa3fb2a5a31 735 /// calculated and its value is in the
WiredHome 167:8aa3fb2a5a31 736 /// output argument.
WiredHome 167:8aa3fb2a5a31 737 /// NOT_OK - an error was detected and the
WiredHome 167:8aa3fb2a5a31 738 /// function failed to return a valid
WiredHome 167:8aa3fb2a5a31 739 /// set of matrix values.
WiredHome 167:8aa3fb2a5a31 740 /// The only time this sample code returns
WiredHome 167:8aa3fb2a5a31 741 /// NOT_OK is when Divider == 0
WiredHome 167:8aa3fb2a5a31 742 ///
WiredHome 167:8aa3fb2a5a31 743 ///
WiredHome 167:8aa3fb2a5a31 744 ///
WiredHome 167:8aa3fb2a5a31 745 /// NOTE! NOTE! NOTE!
WiredHome 167:8aa3fb2a5a31 746 ///
WiredHome 167:8aa3fb2a5a31 747 /// setCalibrationMatrix() and getDisplayPoint() will do fine
WiredHome 167:8aa3fb2a5a31 748 /// for you as they are, provided that your digitizer
WiredHome 167:8aa3fb2a5a31 749 /// resolution does not exceed 10 bits (1024 values). Higher
WiredHome 167:8aa3fb2a5a31 750 /// resolutions may cause the integer operations to overflow
WiredHome 167:8aa3fb2a5a31 751 /// and return incorrect values. If you wish to use these
WiredHome 167:8aa3fb2a5a31 752 /// functions with digitizer resolutions of 12 bits (4096
WiredHome 167:8aa3fb2a5a31 753 /// values) you will either have to a) use 64-bit signed
WiredHome 167:8aa3fb2a5a31 754 /// integer variables and math, or b) judiciously modify the
WiredHome 167:8aa3fb2a5a31 755 /// operations to scale results by a factor of 2 or even 4.
WiredHome 167:8aa3fb2a5a31 756 ///
WiredHome 167:8aa3fb2a5a31 757 /// </pre>
WiredHome 167:8aa3fb2a5a31 758 ///
WiredHome 81:01da2e34283d 759 RetCode_t RA8875::TouchPanelComputeCalibration(point_t * displayPtr, point_t * screenPtr, tpMatrix_t * matrixPtr)
WiredHome 78:faf49c381591 760 {
WiredHome 78:faf49c381591 761 RetCode_t retValue = noerror;
WiredHome 78:faf49c381591 762
WiredHome 78:faf49c381591 763 tpMatrix.Divider = ((screenPtr[0].x - screenPtr[2].x) * (screenPtr[1].y - screenPtr[2].y)) -
WiredHome 78:faf49c381591 764 ((screenPtr[1].x - screenPtr[2].x) * (screenPtr[0].y - screenPtr[2].y)) ;
WiredHome 78:faf49c381591 765
WiredHome 78:faf49c381591 766 if( tpMatrix.Divider == 0 ) {
WiredHome 78:faf49c381591 767 retValue = bad_parameter;
WiredHome 78:faf49c381591 768 } else {
WiredHome 78:faf49c381591 769 tpMatrix.An = ((displayPtr[0].x - displayPtr[2].x) * (screenPtr[1].y - screenPtr[2].y)) -
WiredHome 78:faf49c381591 770 ((displayPtr[1].x - displayPtr[2].x) * (screenPtr[0].y - screenPtr[2].y)) ;
WiredHome 78:faf49c381591 771
WiredHome 78:faf49c381591 772 tpMatrix.Bn = ((screenPtr[0].x - screenPtr[2].x) * (displayPtr[1].x - displayPtr[2].x)) -
WiredHome 78:faf49c381591 773 ((displayPtr[0].x - displayPtr[2].x) * (screenPtr[1].x - screenPtr[2].x)) ;
WiredHome 78:faf49c381591 774
WiredHome 78:faf49c381591 775 tpMatrix.Cn = (screenPtr[2].x * displayPtr[1].x - screenPtr[1].x * displayPtr[2].x) * screenPtr[0].y +
WiredHome 78:faf49c381591 776 (screenPtr[0].x * displayPtr[2].x - screenPtr[2].x * displayPtr[0].x) * screenPtr[1].y +
WiredHome 78:faf49c381591 777 (screenPtr[1].x * displayPtr[0].x - screenPtr[0].x * displayPtr[1].x) * screenPtr[2].y ;
WiredHome 78:faf49c381591 778
WiredHome 78:faf49c381591 779 tpMatrix.Dn = ((displayPtr[0].y - displayPtr[2].y) * (screenPtr[1].y - screenPtr[2].y)) -
WiredHome 78:faf49c381591 780 ((displayPtr[1].y - displayPtr[2].y) * (screenPtr[0].y - screenPtr[2].y)) ;
WiredHome 78:faf49c381591 781
WiredHome 78:faf49c381591 782 tpMatrix.En = ((screenPtr[0].x - screenPtr[2].x) * (displayPtr[1].y - displayPtr[2].y)) -
WiredHome 78:faf49c381591 783 ((displayPtr[0].y - displayPtr[2].y) * (screenPtr[1].x - screenPtr[2].x)) ;
WiredHome 78:faf49c381591 784
WiredHome 78:faf49c381591 785 tpMatrix.Fn = (screenPtr[2].x * displayPtr[1].y - screenPtr[1].x * displayPtr[2].y) * screenPtr[0].y +
WiredHome 78:faf49c381591 786 (screenPtr[0].x * displayPtr[2].y - screenPtr[2].x * displayPtr[0].y) * screenPtr[1].y +
WiredHome 78:faf49c381591 787 (screenPtr[1].x * displayPtr[0].y - screenPtr[0].x * displayPtr[1].y) * screenPtr[2].y ;
WiredHome 83:7bad0068cca0 788 touchState = no_touch;
WiredHome 78:faf49c381591 789 if (matrixPtr)
WiredHome 78:faf49c381591 790 memcpy(matrixPtr, &tpMatrix, sizeof(tpMatrix_t));
WiredHome 78:faf49c381591 791 }
WiredHome 78:faf49c381591 792 return( retValue ) ;
WiredHome 78:faf49c381591 793 }
WiredHome 78:faf49c381591 794
WiredHome 157:1565f38ca44b 795 void RA8875::ResTouchPanelCfg(const char * _tpFQFN, const char * _tpCalMessage)
WiredHome 157:1565f38ca44b 796 {
WiredHome 157:1565f38ca44b 797 tpFQFN = _tpFQFN;
WiredHome 157:1565f38ca44b 798 tpCalMessage = _tpCalMessage;
WiredHome 157:1565f38ca44b 799 }
WiredHome 157:1565f38ca44b 800
WiredHome 157:1565f38ca44b 801
WiredHome 157:1565f38ca44b 802 RetCode_t RA8875::_internal_ts_cal()
WiredHome 157:1565f38ca44b 803 {
WiredHome 157:1565f38ca44b 804 FILE * fh;
WiredHome 157:1565f38ca44b 805 tpMatrix_t matrix;
WiredHome 157:1565f38ca44b 806 RetCode_t r = noerror;
WiredHome 190:3132b7dfad82 807
WiredHome 157:1565f38ca44b 808 if (tpFQFN) {
WiredHome 157:1565f38ca44b 809 fh = fopen(tpFQFN, "rb");
WiredHome 157:1565f38ca44b 810 if (fh) {
WiredHome 157:1565f38ca44b 811 fread(&matrix, sizeof(tpMatrix_t), 1, fh);
WiredHome 157:1565f38ca44b 812 fclose(fh);
WiredHome 157:1565f38ca44b 813 TouchPanelSetMatrix(&matrix);
WiredHome 157:1565f38ca44b 814 } else {
WiredHome 157:1565f38ca44b 815 r = TouchPanelCalibrate(tpCalMessage, &matrix);
WiredHome 157:1565f38ca44b 816 if (r == noerror) {
WiredHome 157:1565f38ca44b 817 fh = fopen(tpFQFN, "wb");
WiredHome 157:1565f38ca44b 818 if (fh) {
WiredHome 157:1565f38ca44b 819 fwrite(&matrix, sizeof(tpMatrix_t), 1, fh);
WiredHome 157:1565f38ca44b 820 fclose(fh);
WiredHome 157:1565f38ca44b 821 INFO(" tp cal written to '%s'.", tpFQFN);
WiredHome 157:1565f38ca44b 822 } else {
WiredHome 157:1565f38ca44b 823 ERR(" couldn't open tpcal file '%s'.", tpFQFN);
WiredHome 157:1565f38ca44b 824 r = file_not_found;
WiredHome 157:1565f38ca44b 825 }
WiredHome 157:1565f38ca44b 826 } else {
WiredHome 157:1565f38ca44b 827 ERR("error return: %d", r);
WiredHome 157:1565f38ca44b 828 }
WiredHome 157:1565f38ca44b 829 HexDump("TPCal", (const uint8_t *)&matrix, sizeof(tpMatrix_t));
WiredHome 157:1565f38ca44b 830 cls();
WiredHome 157:1565f38ca44b 831 }
WiredHome 157:1565f38ca44b 832 }
WiredHome 157:1565f38ca44b 833 return r;
WiredHome 157:1565f38ca44b 834 }
WiredHome 157:1565f38ca44b 835
WiredHome 157:1565f38ca44b 836
WiredHome 157:1565f38ca44b 837
WiredHome 124:1690a7ae871c 838 ////////////////// Capacitive Touch Panel
WiredHome 124:1690a7ae871c 839
WiredHome 165:695c24cc5197 840 uint8_t RA8875::FT5206_ReadRegU8(uint8_t reg) {
WiredHome 124:1690a7ae871c 841 char val;
WiredHome 190:3132b7dfad82 842
WiredHome 124:1690a7ae871c 843 m_i2c->write(m_addr, (const char *)&reg, 1);
WiredHome 124:1690a7ae871c 844 m_i2c->read(m_addr, &val, 1);
WiredHome 181:0032d1b8f5d4 845 //INFO("ReadReg %02X, Val %02X", reg, val);
WiredHome 124:1690a7ae871c 846 return (uint8_t)val;
WiredHome 124:1690a7ae871c 847 }
WiredHome 124:1690a7ae871c 848
WiredHome 124:1690a7ae871c 849 // Interrupt for touch detection
WiredHome 124:1690a7ae871c 850 void RA8875::TouchPanelISR(void)
WiredHome 124:1690a7ae871c 851 {
WiredHome 165:695c24cc5197 852 if (useTouchPanel == TP_FT5206) {
WiredHome 165:695c24cc5197 853 if (FT5206_TouchPositions())
WiredHome 165:695c24cc5197 854 panelTouched = true;
WiredHome 165:695c24cc5197 855 } else if (useTouchPanel == TP_GSL1680) {
WiredHome 165:695c24cc5197 856 if (GSL1680_TouchPositions())
WiredHome 165:695c24cc5197 857 panelTouched = true;
WiredHome 165:695c24cc5197 858 }
WiredHome 124:1690a7ae871c 859 }
WiredHome 124:1690a7ae871c 860
WiredHome 124:1690a7ae871c 861
WiredHome 78:faf49c381591 862 // #### end of touch panel code additions