A library with drivers for different peripherals on the LPC4088 QuickStart Board or related add-on boards.

Dependencies:   FATFileSystem

Dependents:   LPC4088test LPC4088test_ledonly LPC4088test_deleteall LPC4088_RAMtest ... more

Committer:
embeddedartists
Date:
Thu Oct 31 13:23:11 2013 +0000
Revision:
6:405c6e5a4eaf
Parent:
4:b32cf4ef45c5
Child:
12:15597e45eea0
Updated SPI clock frequency for TSC2046

Who changed what in which revision?

UserRevisionLine numberNew contents of line
embeddedartists 0:0fdadbc3d852 1
embeddedartists 0:0fdadbc3d852 2 #include "mbed.h"
embeddedartists 4:b32cf4ef45c5 3 #include "mbed_debug.h"
embeddedartists 0:0fdadbc3d852 4 #include "TSC2046.h"
embeddedartists 0:0fdadbc3d852 5
embeddedartists 0:0fdadbc3d852 6 #ifndef ABS
embeddedartists 0:0fdadbc3d852 7 #define ABS(x) ( ((int32_t)(x)) < 0 ? (-(x)) : (x))
embeddedartists 0:0fdadbc3d852 8 #endif
embeddedartists 0:0fdadbc3d852 9
embeddedartists 0:0fdadbc3d852 10 #define ADS_START (1 << 7)
embeddedartists 0:0fdadbc3d852 11 #define ADS_A2A1A0_d_y (1 << 4) /* differential */
embeddedartists 0:0fdadbc3d852 12 #define ADS_A2A1A0_d_z1 (3 << 4) /* differential */
embeddedartists 0:0fdadbc3d852 13 #define ADS_A2A1A0_d_z2 (4 << 4) /* differential */
embeddedartists 0:0fdadbc3d852 14 #define ADS_A2A1A0_d_x (5 << 4) /* differential */
embeddedartists 0:0fdadbc3d852 15 #define ADS_A2A1A0_temp0 (0 << 4) /* non-differential */
embeddedartists 0:0fdadbc3d852 16 #define ADS_A2A1A0_vbatt (2 << 4) /* non-differential */
embeddedartists 0:0fdadbc3d852 17 #define ADS_A2A1A0_vaux (6 << 4) /* non-differential */
embeddedartists 0:0fdadbc3d852 18 #define ADS_A2A1A0_temp1 (7 << 4) /* non-differential */
embeddedartists 0:0fdadbc3d852 19 #define ADS_8_BIT (1 << 3)
embeddedartists 0:0fdadbc3d852 20 #define ADS_12_BIT (0 << 3)
embeddedartists 0:0fdadbc3d852 21 #define ADS_SER (1 << 2) /* non-differential */
embeddedartists 0:0fdadbc3d852 22 #define ADS_DFR (0 << 2) /* differential */
embeddedartists 0:0fdadbc3d852 23 #define ADS_PD10_PDOWN (0 << 0) /* lowpower mode + penirq */
embeddedartists 0:0fdadbc3d852 24 #define ADS_PD10_ADC_ON (1 << 0) /* ADC on */
embeddedartists 0:0fdadbc3d852 25 #define ADS_PD10_REF_ON (2 << 0) /* vREF on + penirq */
embeddedartists 0:0fdadbc3d852 26 #define ADS_PD10_ALL_ON (3 << 0) /* ADC + vREF on */
embeddedartists 0:0fdadbc3d852 27
embeddedartists 0:0fdadbc3d852 28
embeddedartists 0:0fdadbc3d852 29 #define READ_12BIT_DFR(d, adc, vref) (ADS_START | d \
embeddedartists 0:0fdadbc3d852 30 | ADS_12_BIT | ADS_DFR | \
embeddedartists 0:0fdadbc3d852 31 (adc ? ADS_PD10_ADC_ON : 0) | (vref ? ADS_PD10_REF_ON : 0))
embeddedartists 0:0fdadbc3d852 32
embeddedartists 0:0fdadbc3d852 33 #define READ_Y(vref) (READ_12BIT_DFR(ADS_A2A1A0_d_y, 1, vref))
embeddedartists 0:0fdadbc3d852 34 #define READ_Z1(vref) (READ_12BIT_DFR(ADS_A2A1A0_d_z1, 1, vref))
embeddedartists 0:0fdadbc3d852 35 #define READ_Z2(vref) (READ_12BIT_DFR(ADS_A2A1A0_d_z2, 1, vref))
embeddedartists 0:0fdadbc3d852 36 #define READ_X(vref) (READ_12BIT_DFR(ADS_A2A1A0_d_x, 1, vref))
embeddedartists 0:0fdadbc3d852 37 #define PWRDOWN (READ_12BIT_DFR(ADS_A2A1A0_d_y, 0, 0)) /* LAST */
embeddedartists 0:0fdadbc3d852 38
embeddedartists 0:0fdadbc3d852 39 /* single-ended samples need to first power up reference voltage;
embeddedartists 0:0fdadbc3d852 40 * we leave both ADC and VREF powered
embeddedartists 0:0fdadbc3d852 41 */
embeddedartists 0:0fdadbc3d852 42 #define READ_12BIT_SER(x) (ADS_START | x \
embeddedartists 0:0fdadbc3d852 43 | ADS_12_BIT | ADS_SER)
embeddedartists 0:0fdadbc3d852 44
embeddedartists 0:0fdadbc3d852 45 #define REF_ON (READ_12BIT_DFR(ADS_A2A1A0_d_x, 1, 1))
embeddedartists 0:0fdadbc3d852 46 #define REF_OFF (READ_12BIT_DFR(ADS_A2A1A0_d_y, 0, 0))
embeddedartists 0:0fdadbc3d852 47
embeddedartists 0:0fdadbc3d852 48 #define DEBOUNCE_MAX 10
embeddedartists 0:0fdadbc3d852 49 #define DEBOUNCE_TOL 3
embeddedartists 0:0fdadbc3d852 50
embeddedartists 4:b32cf4ef45c5 51
embeddedartists 0:0fdadbc3d852 52 TSC2046::TSC2046(PinName mosi, PinName miso, PinName sck, PinName cs) :
embeddedartists 0:0fdadbc3d852 53 _spi(mosi, miso, sck), _cs(cs)
embeddedartists 0:0fdadbc3d852 54 {
embeddedartists 0:0fdadbc3d852 55 _cs = 1; // active low
embeddedartists 0:0fdadbc3d852 56
embeddedartists 0:0fdadbc3d852 57 _spi.format(8, 3);
embeddedartists 6:405c6e5a4eaf 58
embeddedartists 6:405c6e5a4eaf 59 // We are limiting the clock rate to 500000 since
embeddedartists 6:405c6e5a4eaf 60 // we have experienced a lot of noise when running with
embeddedartists 6:405c6e5a4eaf 61 // higher rate. It has not been examined why there is a
embeddedartists 6:405c6e5a4eaf 62 // lot of noise with higher rate.
embeddedartists 6:405c6e5a4eaf 63 _spi.frequency(500000);
embeddedartists 0:0fdadbc3d852 64 _calibrated = false;
embeddedartists 0:0fdadbc3d852 65 _initialized = false;
embeddedartists 4:b32cf4ef45c5 66
embeddedartists 4:b32cf4ef45c5 67 _calibPoint = TSC2046_NUM_CALIB_POINTS+1;
embeddedartists 4:b32cf4ef45c5 68
embeddedartists 4:b32cf4ef45c5 69 _insetPx = 15;
embeddedartists 4:b32cf4ef45c5 70 }
embeddedartists 4:b32cf4ef45c5 71
embeddedartists 4:b32cf4ef45c5 72 bool TSC2046::init(uint16_t width, uint16_t height) {
embeddedartists 4:b32cf4ef45c5 73 _width = width;
embeddedartists 4:b32cf4ef45c5 74 _height = height;
embeddedartists 4:b32cf4ef45c5 75
embeddedartists 4:b32cf4ef45c5 76 _cs = 0;
embeddedartists 4:b32cf4ef45c5 77
embeddedartists 4:b32cf4ef45c5 78 _spi.write(REF_ON);
embeddedartists 4:b32cf4ef45c5 79 _spi.write((READ_12BIT_SER(ADS_A2A1A0_vaux) | ADS_PD10_ALL_ON));
embeddedartists 4:b32cf4ef45c5 80 _spi.write(PWRDOWN);
embeddedartists 4:b32cf4ef45c5 81
embeddedartists 4:b32cf4ef45c5 82 _cs = 1;
embeddedartists 4:b32cf4ef45c5 83
embeddedartists 4:b32cf4ef45c5 84
embeddedartists 4:b32cf4ef45c5 85 _initialized = true;
embeddedartists 4:b32cf4ef45c5 86
embeddedartists 4:b32cf4ef45c5 87 return true;
embeddedartists 0:0fdadbc3d852 88 }
embeddedartists 0:0fdadbc3d852 89
embeddedartists 0:0fdadbc3d852 90
embeddedartists 4:b32cf4ef45c5 91 bool TSC2046::read(touchCoordinate_t &coord) {
embeddedartists 0:0fdadbc3d852 92
embeddedartists 0:0fdadbc3d852 93 touchCoordinate_t tmpCoord;
embeddedartists 0:0fdadbc3d852 94 calibPoint_t displayPoint;
embeddedartists 0:0fdadbc3d852 95 calibPoint_t screenSample;
embeddedartists 0:0fdadbc3d852 96
embeddedartists 4:b32cf4ef45c5 97 if (!_initialized) return false;
embeddedartists 4:b32cf4ef45c5 98
embeddedartists 0:0fdadbc3d852 99
embeddedartists 0:0fdadbc3d852 100 readAndFilter(tmpCoord);
embeddedartists 0:0fdadbc3d852 101
embeddedartists 0:0fdadbc3d852 102 _cs = 0;
embeddedartists 0:0fdadbc3d852 103 _spi.write(PWRDOWN);
embeddedartists 0:0fdadbc3d852 104 _cs = 1;
embeddedartists 0:0fdadbc3d852 105
embeddedartists 0:0fdadbc3d852 106 coord.z = tmpCoord.z;
embeddedartists 0:0fdadbc3d852 107
embeddedartists 0:0fdadbc3d852 108 if (_calibrated) {
embeddedartists 0:0fdadbc3d852 109 screenSample.x = tmpCoord.x;
embeddedartists 0:0fdadbc3d852 110 screenSample.y = tmpCoord.y;
embeddedartists 0:0fdadbc3d852 111
embeddedartists 0:0fdadbc3d852 112 getDisplayPoint(&displayPoint, &screenSample, &_calibMatrix);
embeddedartists 0:0fdadbc3d852 113
embeddedartists 0:0fdadbc3d852 114 coord.x = displayPoint.x;
embeddedartists 0:0fdadbc3d852 115 coord.y = displayPoint.y;
embeddedartists 0:0fdadbc3d852 116 }
embeddedartists 0:0fdadbc3d852 117 else {
embeddedartists 0:0fdadbc3d852 118 coord.x = tmpCoord.x;
embeddedartists 0:0fdadbc3d852 119 coord.y = tmpCoord.y;
embeddedartists 0:0fdadbc3d852 120 }
embeddedartists 0:0fdadbc3d852 121
embeddedartists 4:b32cf4ef45c5 122 return true;
embeddedartists 0:0fdadbc3d852 123
embeddedartists 0:0fdadbc3d852 124 }
embeddedartists 0:0fdadbc3d852 125
embeddedartists 4:b32cf4ef45c5 126 bool TSC2046::calibrateStart() {
embeddedartists 4:b32cf4ef45c5 127 if (!_initialized) return false;
embeddedartists 4:b32cf4ef45c5 128
embeddedartists 4:b32cf4ef45c5 129 _calibPoint = 0;
embeddedartists 4:b32cf4ef45c5 130
embeddedartists 4:b32cf4ef45c5 131 return true;
embeddedartists 4:b32cf4ef45c5 132 }
embeddedartists 4:b32cf4ef45c5 133
embeddedartists 4:b32cf4ef45c5 134 bool TSC2046::getNextCalibratePoint(uint16_t* x, uint16_t* y) {
embeddedartists 4:b32cf4ef45c5 135 touchCoordinate_t coord;
embeddedartists 4:b32cf4ef45c5 136
embeddedartists 4:b32cf4ef45c5 137 if (!_initialized) return false;
embeddedartists 4:b32cf4ef45c5 138
embeddedartists 4:b32cf4ef45c5 139 if (x == NULL || y == NULL) return false;
embeddedartists 4:b32cf4ef45c5 140
embeddedartists 4:b32cf4ef45c5 141 if (_calibPoint >= TSC2046_NUM_CALIB_POINTS) return false;
embeddedartists 4:b32cf4ef45c5 142
embeddedartists 4:b32cf4ef45c5 143 getCalibratePoint(_calibPoint, &coord.x, &coord.y);
embeddedartists 4:b32cf4ef45c5 144
embeddedartists 4:b32cf4ef45c5 145 *x = (uint16_t)coord.x;
embeddedartists 4:b32cf4ef45c5 146 *y = (uint16_t)coord.y;
embeddedartists 4:b32cf4ef45c5 147 _calibrateValues[_calibPoint][0] = coord;
embeddedartists 4:b32cf4ef45c5 148
embeddedartists 4:b32cf4ef45c5 149 return true;
embeddedartists 4:b32cf4ef45c5 150 }
embeddedartists 4:b32cf4ef45c5 151
embeddedartists 4:b32cf4ef45c5 152 bool TSC2046::waitForCalibratePoint(bool* morePoints, uint32_t timeout) {
embeddedartists 4:b32cf4ef45c5 153 int result = 0;
embeddedartists 4:b32cf4ef45c5 154 bool ret = false;
embeddedartists 4:b32cf4ef45c5 155 int32_t x = 0;
embeddedartists 4:b32cf4ef45c5 156 int32_t y = 0;
embeddedartists 4:b32cf4ef45c5 157 touchCoordinate_t coord;
embeddedartists 4:b32cf4ef45c5 158
embeddedartists 4:b32cf4ef45c5 159 if (!_initialized) return false;
embeddedartists 4:b32cf4ef45c5 160
embeddedartists 4:b32cf4ef45c5 161 do {
embeddedartists 4:b32cf4ef45c5 162 if (morePoints == NULL || _calibPoint >= TSC2046_NUM_CALIB_POINTS) {
embeddedartists 4:b32cf4ef45c5 163 break;
embeddedartists 4:b32cf4ef45c5 164 }
embeddedartists 4:b32cf4ef45c5 165
embeddedartists 4:b32cf4ef45c5 166 result = waitForTouch(&x, &y, timeout);
embeddedartists 4:b32cf4ef45c5 167 if (result != 0) {
embeddedartists 4:b32cf4ef45c5 168 debug("wait for touch response failed (%d)\n", result);
embeddedartists 4:b32cf4ef45c5 169 break;
embeddedartists 4:b32cf4ef45c5 170 }
embeddedartists 4:b32cf4ef45c5 171
embeddedartists 4:b32cf4ef45c5 172 coord.x = x;
embeddedartists 4:b32cf4ef45c5 173 coord.y = y;
embeddedartists 4:b32cf4ef45c5 174 _calibrateValues[_calibPoint][1] = coord;
embeddedartists 4:b32cf4ef45c5 175
embeddedartists 4:b32cf4ef45c5 176 _calibPoint++;
embeddedartists 4:b32cf4ef45c5 177 *morePoints = (_calibPoint < TSC2046_NUM_CALIB_POINTS);
embeddedartists 4:b32cf4ef45c5 178
embeddedartists 4:b32cf4ef45c5 179 if (!(*morePoints)) {
embeddedartists 4:b32cf4ef45c5 180
embeddedartists 4:b32cf4ef45c5 181 calibrate(
embeddedartists 4:b32cf4ef45c5 182 _calibrateValues[0][0],
embeddedartists 4:b32cf4ef45c5 183 _calibrateValues[1][0],
embeddedartists 4:b32cf4ef45c5 184 _calibrateValues[2][0],
embeddedartists 4:b32cf4ef45c5 185 _calibrateValues[0][1],
embeddedartists 4:b32cf4ef45c5 186 _calibrateValues[1][1],
embeddedartists 4:b32cf4ef45c5 187 _calibrateValues[2][1]);
embeddedartists 4:b32cf4ef45c5 188 }
embeddedartists 4:b32cf4ef45c5 189
embeddedartists 4:b32cf4ef45c5 190
embeddedartists 4:b32cf4ef45c5 191 ret = true;
embeddedartists 4:b32cf4ef45c5 192
embeddedartists 4:b32cf4ef45c5 193 } while (0);
embeddedartists 4:b32cf4ef45c5 194
embeddedartists 4:b32cf4ef45c5 195
embeddedartists 4:b32cf4ef45c5 196
embeddedartists 4:b32cf4ef45c5 197 if (!ret) {
embeddedartists 4:b32cf4ef45c5 198 // calibration must restart if an error occurred
embeddedartists 4:b32cf4ef45c5 199 _calibPoint = TSC2046_NUM_CALIB_POINTS+1;
embeddedartists 4:b32cf4ef45c5 200 }
embeddedartists 4:b32cf4ef45c5 201
embeddedartists 4:b32cf4ef45c5 202
embeddedartists 4:b32cf4ef45c5 203
embeddedartists 4:b32cf4ef45c5 204 return ret;
embeddedartists 4:b32cf4ef45c5 205
embeddedartists 0:0fdadbc3d852 206 }
embeddedartists 0:0fdadbc3d852 207
embeddedartists 0:0fdadbc3d852 208
embeddedartists 4:b32cf4ef45c5 209 bool TSC2046::calibrate(touchCoordinate_t* values, int numValues) {
embeddedartists 4:b32cf4ef45c5 210 if (values == NULL || numValues < TSC2046_NUM_CALIB_POINTS) return false;
embeddedartists 4:b32cf4ef45c5 211
embeddedartists 4:b32cf4ef45c5 212 touchCoordinate_t ref[TSC2046_NUM_CALIB_POINTS];
embeddedartists 4:b32cf4ef45c5 213 touchCoordinate_t scr[TSC2046_NUM_CALIB_POINTS];
embeddedartists 0:0fdadbc3d852 214
embeddedartists 4:b32cf4ef45c5 215 for (int i = 0; i < TSC2046_NUM_CALIB_POINTS; i++) {
embeddedartists 4:b32cf4ef45c5 216 getCalibratePoint(i, &(ref[i].x), &(ref[i].y));
embeddedartists 4:b32cf4ef45c5 217 scr[i] = values[i];
embeddedartists 4:b32cf4ef45c5 218 }
embeddedartists 4:b32cf4ef45c5 219
embeddedartists 4:b32cf4ef45c5 220 calibrate(ref[0], ref[1], ref[2], scr[0], scr[1], scr[2]);
embeddedartists 0:0fdadbc3d852 221
embeddedartists 4:b32cf4ef45c5 222 return true;
embeddedartists 4:b32cf4ef45c5 223 }
embeddedartists 4:b32cf4ef45c5 224
embeddedartists 4:b32cf4ef45c5 225
embeddedartists 4:b32cf4ef45c5 226 bool TSC2046::getCalibrationValues(touchCoordinate_t* values, int numValues) {
embeddedartists 4:b32cf4ef45c5 227 if (values == NULL || numValues < TSC2046_NUM_CALIB_POINTS) return false;
embeddedartists 4:b32cf4ef45c5 228 if (!_calibrated) return false;
embeddedartists 0:0fdadbc3d852 229
embeddedartists 4:b32cf4ef45c5 230 for (int i = 0; i < TSC2046_NUM_CALIB_POINTS; i++) {
embeddedartists 4:b32cf4ef45c5 231 values[i] = _calibrateValues[i][1];
embeddedartists 4:b32cf4ef45c5 232 }
embeddedartists 4:b32cf4ef45c5 233
embeddedartists 4:b32cf4ef45c5 234 return true;
embeddedartists 0:0fdadbc3d852 235 }
embeddedartists 0:0fdadbc3d852 236
embeddedartists 4:b32cf4ef45c5 237
embeddedartists 0:0fdadbc3d852 238 void TSC2046::readAndFilter(touchCoordinate_t &coord)
embeddedartists 0:0fdadbc3d852 239 {
embeddedartists 0:0fdadbc3d852 240 int32_t ix, iy, iz1, iz2 = 0;
embeddedartists 0:0fdadbc3d852 241 int32_t lastx, lasty, lastz1, lastz2 = 0;
embeddedartists 0:0fdadbc3d852 242 int i = 0;
embeddedartists 0:0fdadbc3d852 243
embeddedartists 0:0fdadbc3d852 244 coord.x = 0;
embeddedartists 0:0fdadbc3d852 245 coord.y = 0;
embeddedartists 0:0fdadbc3d852 246 coord.z = 0;
embeddedartists 0:0fdadbc3d852 247
embeddedartists 0:0fdadbc3d852 248 lasty = getFilteredValue(READ_Y(0));
embeddedartists 0:0fdadbc3d852 249 lasty >>= 3;
embeddedartists 0:0fdadbc3d852 250 if (lasty >= 4095) {
embeddedartists 0:0fdadbc3d852 251 lasty = 0;
embeddedartists 0:0fdadbc3d852 252 }
embeddedartists 0:0fdadbc3d852 253
embeddedartists 0:0fdadbc3d852 254 lastx = getFilteredValue(READ_X(0));
embeddedartists 0:0fdadbc3d852 255 lastx >>= 3;
embeddedartists 0:0fdadbc3d852 256 if (lastx >= 4095) {
embeddedartists 0:0fdadbc3d852 257 lastx = 0;
embeddedartists 0:0fdadbc3d852 258 }
embeddedartists 0:0fdadbc3d852 259
embeddedartists 0:0fdadbc3d852 260 lastz1 = getFilteredValue(READ_Z1(0));
embeddedartists 0:0fdadbc3d852 261 lastz1 >>= 3;
embeddedartists 0:0fdadbc3d852 262
embeddedartists 0:0fdadbc3d852 263 lastz2 = getFilteredValue(READ_Z2(0));
embeddedartists 0:0fdadbc3d852 264 lastz2 >>= 3;
embeddedartists 0:0fdadbc3d852 265
embeddedartists 0:0fdadbc3d852 266
embeddedartists 0:0fdadbc3d852 267 if (lastx && lastz1) {
embeddedartists 0:0fdadbc3d852 268 coord.z = (lastx * ABS(lastz2 - lastz1)) / lastz1;
embeddedartists 0:0fdadbc3d852 269 }
embeddedartists 0:0fdadbc3d852 270 else {
embeddedartists 0:0fdadbc3d852 271 coord.z = 0;
embeddedartists 0:0fdadbc3d852 272 }
embeddedartists 0:0fdadbc3d852 273
embeddedartists 0:0fdadbc3d852 274 if (coord.z > 20000) {
embeddedartists 0:0fdadbc3d852 275 coord.z = 0;
embeddedartists 0:0fdadbc3d852 276 }
embeddedartists 0:0fdadbc3d852 277
embeddedartists 0:0fdadbc3d852 278 if (coord.z == 0) {
embeddedartists 0:0fdadbc3d852 279 return;
embeddedartists 0:0fdadbc3d852 280 }
embeddedartists 0:0fdadbc3d852 281
embeddedartists 0:0fdadbc3d852 282 for (i = 0; i < DEBOUNCE_MAX; i++) {
embeddedartists 0:0fdadbc3d852 283 iy = getFilteredValue(READ_Y(0));
embeddedartists 0:0fdadbc3d852 284 iy >>= 3;
embeddedartists 0:0fdadbc3d852 285
embeddedartists 0:0fdadbc3d852 286 if (ABS (lasty - iy) <= DEBOUNCE_TOL) {
embeddedartists 0:0fdadbc3d852 287 break;
embeddedartists 0:0fdadbc3d852 288 }
embeddedartists 0:0fdadbc3d852 289
embeddedartists 0:0fdadbc3d852 290 lasty = iy;
embeddedartists 0:0fdadbc3d852 291 }
embeddedartists 0:0fdadbc3d852 292
embeddedartists 0:0fdadbc3d852 293 for (i = 0; i < DEBOUNCE_MAX; i++) {
embeddedartists 0:0fdadbc3d852 294 ix = getFilteredValue(READ_X(0));
embeddedartists 0:0fdadbc3d852 295 ix >>= 3;
embeddedartists 0:0fdadbc3d852 296 if (ix > 4095) {
embeddedartists 0:0fdadbc3d852 297 ix = 0;
embeddedartists 0:0fdadbc3d852 298 }
embeddedartists 0:0fdadbc3d852 299
embeddedartists 0:0fdadbc3d852 300 if (ABS (lastx - ix) <= DEBOUNCE_TOL) {
embeddedartists 0:0fdadbc3d852 301 break;
embeddedartists 0:0fdadbc3d852 302 }
embeddedartists 0:0fdadbc3d852 303
embeddedartists 0:0fdadbc3d852 304 lastx = ix;
embeddedartists 0:0fdadbc3d852 305 }
embeddedartists 0:0fdadbc3d852 306
embeddedartists 0:0fdadbc3d852 307 for (i = 0; i < DEBOUNCE_MAX; i++) {
embeddedartists 0:0fdadbc3d852 308 iz1 = getFilteredValue(READ_Z1(0));
embeddedartists 0:0fdadbc3d852 309 iz1 >>= 3;
embeddedartists 0:0fdadbc3d852 310
embeddedartists 0:0fdadbc3d852 311 if (ABS (lastz1 - iz1) <= DEBOUNCE_TOL) {
embeddedartists 0:0fdadbc3d852 312 break;
embeddedartists 0:0fdadbc3d852 313 }
embeddedartists 0:0fdadbc3d852 314
embeddedartists 0:0fdadbc3d852 315 lastz1 = iz1;
embeddedartists 0:0fdadbc3d852 316 }
embeddedartists 0:0fdadbc3d852 317
embeddedartists 0:0fdadbc3d852 318 for (i = 0; i < DEBOUNCE_MAX; i++) {
embeddedartists 0:0fdadbc3d852 319 iz2 = getFilteredValue(READ_Z2(0));
embeddedartists 0:0fdadbc3d852 320 iz2 >>= 3;
embeddedartists 0:0fdadbc3d852 321
embeddedartists 0:0fdadbc3d852 322 if (ABS (lastz2 - iz2) <= DEBOUNCE_TOL) {
embeddedartists 0:0fdadbc3d852 323 break;
embeddedartists 0:0fdadbc3d852 324 }
embeddedartists 0:0fdadbc3d852 325
embeddedartists 0:0fdadbc3d852 326 lastz2 = iz2;
embeddedartists 0:0fdadbc3d852 327 }
embeddedartists 0:0fdadbc3d852 328
embeddedartists 0:0fdadbc3d852 329 coord.x = ix;
embeddedartists 0:0fdadbc3d852 330 coord.y = iy;
embeddedartists 0:0fdadbc3d852 331
embeddedartists 0:0fdadbc3d852 332 if (ix && iz1) {
embeddedartists 0:0fdadbc3d852 333 coord.z = (ix * ABS(iz2 - iz1)) / iz1;
embeddedartists 0:0fdadbc3d852 334 }
embeddedartists 0:0fdadbc3d852 335 else {
embeddedartists 0:0fdadbc3d852 336 coord.z = 0;
embeddedartists 0:0fdadbc3d852 337 }
embeddedartists 0:0fdadbc3d852 338
embeddedartists 0:0fdadbc3d852 339 if (coord.z > 20000) {
embeddedartists 0:0fdadbc3d852 340 coord.z = 0;
embeddedartists 0:0fdadbc3d852 341 }
embeddedartists 0:0fdadbc3d852 342
embeddedartists 0:0fdadbc3d852 343 }
embeddedartists 0:0fdadbc3d852 344
embeddedartists 0:0fdadbc3d852 345 int32_t TSC2046::getFilteredValue(int cmd)
embeddedartists 0:0fdadbc3d852 346 {
embeddedartists 0:0fdadbc3d852 347 int32_t a[7];
embeddedartists 0:0fdadbc3d852 348 int32_t tmp = 0;
embeddedartists 0:0fdadbc3d852 349 int i = 0, j = 0;
embeddedartists 0:0fdadbc3d852 350
embeddedartists 0:0fdadbc3d852 351 /*
embeddedartists 0:0fdadbc3d852 352 * Median and averaging filter
embeddedartists 0:0fdadbc3d852 353 *
embeddedartists 0:0fdadbc3d852 354 * 1. Get 7 values
embeddedartists 0:0fdadbc3d852 355 * 2. Sort these values
embeddedartists 0:0fdadbc3d852 356 * 3. Take average of the 3 values in the middle
embeddedartists 0:0fdadbc3d852 357 */
embeddedartists 0:0fdadbc3d852 358
embeddedartists 0:0fdadbc3d852 359 for (i = 0; i < 7; i++) {
embeddedartists 0:0fdadbc3d852 360 a[i] = spiTransfer(cmd);
embeddedartists 0:0fdadbc3d852 361 }
embeddedartists 0:0fdadbc3d852 362
embeddedartists 0:0fdadbc3d852 363 // bubble sort
embeddedartists 0:0fdadbc3d852 364 for (i = 0; i < 7; i++) {
embeddedartists 0:0fdadbc3d852 365 for (j = 0; j < (7-(i+1)); j++) {
embeddedartists 0:0fdadbc3d852 366 if (a[j] > a[j+1]) {
embeddedartists 0:0fdadbc3d852 367 // swap
embeddedartists 0:0fdadbc3d852 368 tmp = a[j];
embeddedartists 0:0fdadbc3d852 369 a[j] = a[j+1];
embeddedartists 0:0fdadbc3d852 370 a[j+1] = tmp;
embeddedartists 0:0fdadbc3d852 371 }
embeddedartists 0:0fdadbc3d852 372 }
embeddedartists 0:0fdadbc3d852 373 }
embeddedartists 0:0fdadbc3d852 374
embeddedartists 0:0fdadbc3d852 375 // average of 3 values in the middle
embeddedartists 0:0fdadbc3d852 376 return ((a[2]+a[3]+a[4])/3);
embeddedartists 0:0fdadbc3d852 377 }
embeddedartists 0:0fdadbc3d852 378
embeddedartists 0:0fdadbc3d852 379 uint16_t TSC2046::spiTransfer(uint8_t cmd)
embeddedartists 0:0fdadbc3d852 380 {
embeddedartists 0:0fdadbc3d852 381 uint8_t data[3];
embeddedartists 0:0fdadbc3d852 382
embeddedartists 0:0fdadbc3d852 383 _cs = 0;
embeddedartists 0:0fdadbc3d852 384
embeddedartists 0:0fdadbc3d852 385 /*data[0] = */_spi.write(cmd);
embeddedartists 0:0fdadbc3d852 386 data[0] = _spi.write(0xff);
embeddedartists 0:0fdadbc3d852 387 data[1] = _spi.write(0xff);
embeddedartists 0:0fdadbc3d852 388
embeddedartists 0:0fdadbc3d852 389 _cs = 1;
embeddedartists 0:0fdadbc3d852 390
embeddedartists 0:0fdadbc3d852 391 return ((data[0] << 8) | data[1]);
embeddedartists 0:0fdadbc3d852 392 }
embeddedartists 0:0fdadbc3d852 393
embeddedartists 4:b32cf4ef45c5 394 void TSC2046::calibrate(touchCoordinate_t &ref1,
embeddedartists 4:b32cf4ef45c5 395 touchCoordinate_t &ref2,
embeddedartists 4:b32cf4ef45c5 396 touchCoordinate_t &ref3,
embeddedartists 4:b32cf4ef45c5 397 touchCoordinate_t &scr1,
embeddedartists 4:b32cf4ef45c5 398 touchCoordinate_t &scr2,
embeddedartists 4:b32cf4ef45c5 399 touchCoordinate_t &scr3) {
embeddedartists 4:b32cf4ef45c5 400
embeddedartists 4:b32cf4ef45c5 401 calibPoint_t disp[3];
embeddedartists 4:b32cf4ef45c5 402 calibPoint_t scr[3];
embeddedartists 4:b32cf4ef45c5 403
embeddedartists 4:b32cf4ef45c5 404 disp[0].x = ref1.x;
embeddedartists 4:b32cf4ef45c5 405 disp[0].y = ref1.y;
embeddedartists 4:b32cf4ef45c5 406 disp[1].x = ref2.x;
embeddedartists 4:b32cf4ef45c5 407 disp[1].y = ref2.y;
embeddedartists 4:b32cf4ef45c5 408 disp[2].x = ref3.x;
embeddedartists 4:b32cf4ef45c5 409 disp[2].y = ref3.y;
embeddedartists 4:b32cf4ef45c5 410
embeddedartists 4:b32cf4ef45c5 411 scr[0].x = scr1.x;
embeddedartists 4:b32cf4ef45c5 412 scr[0].y = scr1.y;
embeddedartists 4:b32cf4ef45c5 413 scr[1].x = scr2.x;
embeddedartists 4:b32cf4ef45c5 414 scr[1].y = scr2.y;
embeddedartists 4:b32cf4ef45c5 415 scr[2].x = scr3.x;
embeddedartists 4:b32cf4ef45c5 416 scr[2].y = scr3.y;
embeddedartists 4:b32cf4ef45c5 417
embeddedartists 4:b32cf4ef45c5 418 setCalibrationMatrix(disp, scr, &_calibMatrix);
embeddedartists 4:b32cf4ef45c5 419
embeddedartists 4:b32cf4ef45c5 420 _calibrated = true;
embeddedartists 4:b32cf4ef45c5 421
embeddedartists 4:b32cf4ef45c5 422 }
embeddedartists 4:b32cf4ef45c5 423
embeddedartists 4:b32cf4ef45c5 424 void TSC2046::getCalibratePoint(int pointNum, int32_t* x, int32_t *y) {
embeddedartists 4:b32cf4ef45c5 425 switch(pointNum) {
embeddedartists 4:b32cf4ef45c5 426 case 0:
embeddedartists 4:b32cf4ef45c5 427 *x = _insetPx;
embeddedartists 4:b32cf4ef45c5 428 *y = _height - _insetPx;
embeddedartists 4:b32cf4ef45c5 429 break;
embeddedartists 4:b32cf4ef45c5 430 case 1:
embeddedartists 4:b32cf4ef45c5 431 *x = _width/2;
embeddedartists 4:b32cf4ef45c5 432 *y = _insetPx;
embeddedartists 4:b32cf4ef45c5 433 break;
embeddedartists 4:b32cf4ef45c5 434 case 2:
embeddedartists 4:b32cf4ef45c5 435 *x = _width - _insetPx;
embeddedartists 4:b32cf4ef45c5 436 *y = _height - _insetPx;
embeddedartists 4:b32cf4ef45c5 437 break;
embeddedartists 4:b32cf4ef45c5 438 }
embeddedartists 4:b32cf4ef45c5 439 }
embeddedartists 4:b32cf4ef45c5 440
embeddedartists 4:b32cf4ef45c5 441 int TSC2046::waitForTouch(int32_t* x, int32_t* y, uint32_t timeout) {
embeddedartists 4:b32cf4ef45c5 442 Timer t;
embeddedartists 4:b32cf4ef45c5 443 touchCoordinate_t coord;
embeddedartists 4:b32cf4ef45c5 444 bool waitForRelease = false;
embeddedartists 4:b32cf4ef45c5 445 int32_t tx = 0;
embeddedartists 4:b32cf4ef45c5 446 int32_t ty = 0;
embeddedartists 4:b32cf4ef45c5 447
embeddedartists 4:b32cf4ef45c5 448
embeddedartists 4:b32cf4ef45c5 449 t.start();
embeddedartists 4:b32cf4ef45c5 450 while (timeout == 0 || ((uint32_t)t.read_ms() < timeout)) {
embeddedartists 4:b32cf4ef45c5 451
embeddedartists 4:b32cf4ef45c5 452 read(coord);
embeddedartists 4:b32cf4ef45c5 453
embeddedartists 4:b32cf4ef45c5 454 if (coord.z == 0 && waitForRelease) {
embeddedartists 4:b32cf4ef45c5 455 *x = tx;
embeddedartists 4:b32cf4ef45c5 456 *y = ty;
embeddedartists 4:b32cf4ef45c5 457 break;
embeddedartists 4:b32cf4ef45c5 458 }
embeddedartists 4:b32cf4ef45c5 459
embeddedartists 4:b32cf4ef45c5 460 if (coord.z > 0) {
embeddedartists 4:b32cf4ef45c5 461 tx = coord.x;
embeddedartists 4:b32cf4ef45c5 462 ty = coord.y;
embeddedartists 4:b32cf4ef45c5 463 waitForRelease = true;
embeddedartists 4:b32cf4ef45c5 464 }
embeddedartists 4:b32cf4ef45c5 465
embeddedartists 4:b32cf4ef45c5 466 wait_ms(10);
embeddedartists 4:b32cf4ef45c5 467 }
embeddedartists 4:b32cf4ef45c5 468
embeddedartists 4:b32cf4ef45c5 469 if (timeout > 0 && (uint32_t)t.read_ms() > timeout) {
embeddedartists 4:b32cf4ef45c5 470 return -1;
embeddedartists 4:b32cf4ef45c5 471 }
embeddedartists 4:b32cf4ef45c5 472
embeddedartists 4:b32cf4ef45c5 473 return 0;
embeddedartists 4:b32cf4ef45c5 474
embeddedartists 4:b32cf4ef45c5 475 }
embeddedartists 4:b32cf4ef45c5 476
embeddedartists 4:b32cf4ef45c5 477
embeddedartists 0:0fdadbc3d852 478
embeddedartists 0:0fdadbc3d852 479 // ############################################################################
embeddedartists 0:0fdadbc3d852 480 // >>>>>>>> Calibrate code >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
embeddedartists 0:0fdadbc3d852 481 // ############################################################################
embeddedartists 0:0fdadbc3d852 482
embeddedartists 0:0fdadbc3d852 483
embeddedartists 0:0fdadbc3d852 484 /*
embeddedartists 0:0fdadbc3d852 485 *
embeddedartists 0:0fdadbc3d852 486 * Copyright (c) 2001, Carlos E. Vidales. All rights reserved.
embeddedartists 0:0fdadbc3d852 487 *
embeddedartists 0:0fdadbc3d852 488 * This sample program was written and put in the public domain
embeddedartists 0:0fdadbc3d852 489 * by Carlos E. Vidales. The program is provided "as is"
embeddedartists 0:0fdadbc3d852 490 * without warranty of any kind, either expressed or implied.
embeddedartists 0:0fdadbc3d852 491 * If you choose to use the program within your own products
embeddedartists 0:0fdadbc3d852 492 * you do so at your own risk, and assume the responsibility
embeddedartists 0:0fdadbc3d852 493 * for servicing, repairing or correcting the program should
embeddedartists 0:0fdadbc3d852 494 * it prove defective in any manner.
embeddedartists 0:0fdadbc3d852 495 * You may copy and distribute the program's source code in any
embeddedartists 0:0fdadbc3d852 496 * medium, provided that you also include in each copy an
embeddedartists 0:0fdadbc3d852 497 * appropriate copyright notice and disclaimer of warranty.
embeddedartists 0:0fdadbc3d852 498 * You may also modify this program and distribute copies of
embeddedartists 0:0fdadbc3d852 499 * it provided that you include prominent notices stating
embeddedartists 0:0fdadbc3d852 500 * that you changed the file(s) and the date of any change,
embeddedartists 0:0fdadbc3d852 501 * and that you do not charge any royalties or licenses for
embeddedartists 0:0fdadbc3d852 502 * its use.
embeddedartists 0:0fdadbc3d852 503 *
embeddedartists 0:0fdadbc3d852 504 *
embeddedartists 0:0fdadbc3d852 505 *
embeddedartists 0:0fdadbc3d852 506 * File Name: calibrate.c
embeddedartists 0:0fdadbc3d852 507 *
embeddedartists 0:0fdadbc3d852 508 *
embeddedartists 0:0fdadbc3d852 509 * This file contains functions that implement calculations
embeddedartists 0:0fdadbc3d852 510 * necessary to obtain calibration factors for a touch screen
embeddedartists 0:0fdadbc3d852 511 * that suffers from multiple distortion effects: namely,
embeddedartists 0:0fdadbc3d852 512 * translation, scaling and rotation.
embeddedartists 0:0fdadbc3d852 513 *
embeddedartists 0:0fdadbc3d852 514 * The following set of equations represent a valid display
embeddedartists 0:0fdadbc3d852 515 * point given a corresponding set of touch screen points:
embeddedartists 0:0fdadbc3d852 516 *
embeddedartists 0:0fdadbc3d852 517 *
embeddedartists 0:0fdadbc3d852 518 * /- -\
embeddedartists 0:0fdadbc3d852 519 * /- -\ /- -\ | |
embeddedartists 0:0fdadbc3d852 520 * | | | | | Xs |
embeddedartists 0:0fdadbc3d852 521 * | Xd | | A B C | | |
embeddedartists 0:0fdadbc3d852 522 * | | = | | * | Ys |
embeddedartists 0:0fdadbc3d852 523 * | Yd | | D E F | | |
embeddedartists 0:0fdadbc3d852 524 * | | | | | 1 |
embeddedartists 0:0fdadbc3d852 525 * \- -/ \- -/ | |
embeddedartists 0:0fdadbc3d852 526 * \- -/
embeddedartists 0:0fdadbc3d852 527 *
embeddedartists 0:0fdadbc3d852 528 *
embeddedartists 0:0fdadbc3d852 529 * where:
embeddedartists 0:0fdadbc3d852 530 *
embeddedartists 0:0fdadbc3d852 531 * (Xd,Yd) represents the desired display point
embeddedartists 0:0fdadbc3d852 532 * coordinates,
embeddedartists 0:0fdadbc3d852 533 *
embeddedartists 0:0fdadbc3d852 534 * (Xs,Ys) represents the available touch screen
embeddedartists 0:0fdadbc3d852 535 * coordinates, and the matrix
embeddedartists 0:0fdadbc3d852 536 *
embeddedartists 0:0fdadbc3d852 537 * /- -\
embeddedartists 0:0fdadbc3d852 538 * |A,B,C|
embeddedartists 0:0fdadbc3d852 539 * |D,E,F| represents the factors used to translate
embeddedartists 0:0fdadbc3d852 540 * \- -/ the available touch screen point values
embeddedartists 0:0fdadbc3d852 541 * into the corresponding display
embeddedartists 0:0fdadbc3d852 542 * coordinates.
embeddedartists 0:0fdadbc3d852 543 *
embeddedartists 0:0fdadbc3d852 544 *
embeddedartists 0:0fdadbc3d852 545 * Note that for practical considerations, the utilitities
embeddedartists 0:0fdadbc3d852 546 * within this file do not use the matrix coefficients as
embeddedartists 0:0fdadbc3d852 547 * defined above, but instead use the following
embeddedartists 0:0fdadbc3d852 548 * equivalents, since floating point math is not used:
embeddedartists 0:0fdadbc3d852 549 *
embeddedartists 0:0fdadbc3d852 550 * A = An/Divider
embeddedartists 0:0fdadbc3d852 551 * B = Bn/Divider
embeddedartists 0:0fdadbc3d852 552 * C = Cn/Divider
embeddedartists 0:0fdadbc3d852 553 * D = Dn/Divider
embeddedartists 0:0fdadbc3d852 554 * E = En/Divider
embeddedartists 0:0fdadbc3d852 555 * F = Fn/Divider
embeddedartists 0:0fdadbc3d852 556 *
embeddedartists 0:0fdadbc3d852 557 *
embeddedartists 0:0fdadbc3d852 558 *
embeddedartists 0:0fdadbc3d852 559 * The functions provided within this file are:
embeddedartists 0:0fdadbc3d852 560 *
embeddedartists 0:0fdadbc3d852 561 * setCalibrationMatrix() - calculates the set of factors
embeddedartists 0:0fdadbc3d852 562 * in the above equation, given
embeddedartists 0:0fdadbc3d852 563 * three sets of test points.
embeddedartists 0:0fdadbc3d852 564 * getDisplayPoint() - returns the actual display
embeddedartists 0:0fdadbc3d852 565 * coordinates, given a set of
embeddedartists 0:0fdadbc3d852 566 * touch screen coordinates.
embeddedartists 0:0fdadbc3d852 567 * translateRawScreenCoordinates() - helper function to transform
embeddedartists 0:0fdadbc3d852 568 * raw screen points into values
embeddedartists 0:0fdadbc3d852 569 * scaled to the desired display
embeddedartists 0:0fdadbc3d852 570 * resolution.
embeddedartists 0:0fdadbc3d852 571 *
embeddedartists 0:0fdadbc3d852 572 *
embeddedartists 0:0fdadbc3d852 573 */
embeddedartists 0:0fdadbc3d852 574
embeddedartists 0:0fdadbc3d852 575
embeddedartists 0:0fdadbc3d852 576 /**********************************************************************
embeddedartists 0:0fdadbc3d852 577 *
embeddedartists 0:0fdadbc3d852 578 * Function: setCalibrationMatrix()
embeddedartists 0:0fdadbc3d852 579 *
embeddedartists 0:0fdadbc3d852 580 * Description: Calling this function with valid input data
embeddedartists 0:0fdadbc3d852 581 * in the display and screen input arguments
embeddedartists 0:0fdadbc3d852 582 * causes the calibration factors between the
embeddedartists 0:0fdadbc3d852 583 * screen and display points to be calculated,
embeddedartists 0:0fdadbc3d852 584 * and the output argument - matrixPtr - to be
embeddedartists 0:0fdadbc3d852 585 * populated.
embeddedartists 0:0fdadbc3d852 586 *
embeddedartists 0:0fdadbc3d852 587 * This function needs to be called only when new
embeddedartists 0:0fdadbc3d852 588 * calibration factors are desired.
embeddedartists 0:0fdadbc3d852 589 *
embeddedartists 0:0fdadbc3d852 590 *
embeddedartists 0:0fdadbc3d852 591 * Argument(s): displayPtr (input) - Pointer to an array of three
embeddedartists 0:0fdadbc3d852 592 * sample, reference points.
embeddedartists 0:0fdadbc3d852 593 * screenPtr (input) - Pointer to the array of touch
embeddedartists 0:0fdadbc3d852 594 * screen points corresponding
embeddedartists 0:0fdadbc3d852 595 * to the reference display points.
embeddedartists 0:0fdadbc3d852 596 * matrixPtr (output) - Pointer to the calibration
embeddedartists 0:0fdadbc3d852 597 * matrix computed for the set
embeddedartists 0:0fdadbc3d852 598 * of points being provided.
embeddedartists 0:0fdadbc3d852 599 *
embeddedartists 0:0fdadbc3d852 600 *
embeddedartists 0:0fdadbc3d852 601 * From the article text, recall that the matrix coefficients are
embeddedartists 0:0fdadbc3d852 602 * resolved to be the following:
embeddedartists 0:0fdadbc3d852 603 *
embeddedartists 0:0fdadbc3d852 604 *
embeddedartists 0:0fdadbc3d852 605 * Divider = (Xs0 - Xs2)*(Ys1 - Ys2) - (Xs1 - Xs2)*(Ys0 - Ys2)
embeddedartists 0:0fdadbc3d852 606 *
embeddedartists 0:0fdadbc3d852 607 *
embeddedartists 0:0fdadbc3d852 608 *
embeddedartists 0:0fdadbc3d852 609 * (Xd0 - Xd2)*(Ys1 - Ys2) - (Xd1 - Xd2)*(Ys0 - Ys2)
embeddedartists 0:0fdadbc3d852 610 * A = ---------------------------------------------------
embeddedartists 0:0fdadbc3d852 611 * Divider
embeddedartists 0:0fdadbc3d852 612 *
embeddedartists 0:0fdadbc3d852 613 *
embeddedartists 0:0fdadbc3d852 614 * (Xs0 - Xs2)*(Xd1 - Xd2) - (Xd0 - Xd2)*(Xs1 - Xs2)
embeddedartists 0:0fdadbc3d852 615 * B = ---------------------------------------------------
embeddedartists 0:0fdadbc3d852 616 * Divider
embeddedartists 0:0fdadbc3d852 617 *
embeddedartists 0:0fdadbc3d852 618 *
embeddedartists 0:0fdadbc3d852 619 * Ys0*(Xs2*Xd1 - Xs1*Xd2) +
embeddedartists 0:0fdadbc3d852 620 * Ys1*(Xs0*Xd2 - Xs2*Xd0) +
embeddedartists 0:0fdadbc3d852 621 * Ys2*(Xs1*Xd0 - Xs0*Xd1)
embeddedartists 0:0fdadbc3d852 622 * C = ---------------------------------------------------
embeddedartists 0:0fdadbc3d852 623 * Divider
embeddedartists 0:0fdadbc3d852 624 *
embeddedartists 0:0fdadbc3d852 625 *
embeddedartists 0:0fdadbc3d852 626 * (Yd0 - Yd2)*(Ys1 - Ys2) - (Yd1 - Yd2)*(Ys0 - Ys2)
embeddedartists 0:0fdadbc3d852 627 * D = ---------------------------------------------------
embeddedartists 0:0fdadbc3d852 628 * Divider
embeddedartists 0:0fdadbc3d852 629 *
embeddedartists 0:0fdadbc3d852 630 *
embeddedartists 0:0fdadbc3d852 631 * (Xs0 - Xs2)*(Yd1 - Yd2) - (Yd0 - Yd2)*(Xs1 - Xs2)
embeddedartists 0:0fdadbc3d852 632 * E = ---------------------------------------------------
embeddedartists 0:0fdadbc3d852 633 * Divider
embeddedartists 0:0fdadbc3d852 634 *
embeddedartists 0:0fdadbc3d852 635 *
embeddedartists 0:0fdadbc3d852 636 * Ys0*(Xs2*Yd1 - Xs1*Yd2) +
embeddedartists 0:0fdadbc3d852 637 * Ys1*(Xs0*Yd2 - Xs2*Yd0) +
embeddedartists 0:0fdadbc3d852 638 * Ys2*(Xs1*Yd0 - Xs0*Yd1)
embeddedartists 0:0fdadbc3d852 639 * F = ---------------------------------------------------
embeddedartists 0:0fdadbc3d852 640 * Divider
embeddedartists 0:0fdadbc3d852 641 *
embeddedartists 0:0fdadbc3d852 642 *
embeddedartists 0:0fdadbc3d852 643 * Return: OK - the calibration matrix was correctly
embeddedartists 0:0fdadbc3d852 644 * calculated and its value is in the
embeddedartists 0:0fdadbc3d852 645 * output argument.
embeddedartists 0:0fdadbc3d852 646 * NOT_OK - an error was detected and the
embeddedartists 0:0fdadbc3d852 647 * function failed to return a valid
embeddedartists 0:0fdadbc3d852 648 * set of matrix values.
embeddedartists 0:0fdadbc3d852 649 * The only time this sample code returns
embeddedartists 0:0fdadbc3d852 650 * NOT_OK is when Divider == 0
embeddedartists 0:0fdadbc3d852 651 *
embeddedartists 0:0fdadbc3d852 652 *
embeddedartists 0:0fdadbc3d852 653 *
embeddedartists 0:0fdadbc3d852 654 * NOTE! NOTE! NOTE!
embeddedartists 0:0fdadbc3d852 655 *
embeddedartists 0:0fdadbc3d852 656 * setCalibrationMatrix() and getDisplayPoint() will do fine
embeddedartists 0:0fdadbc3d852 657 * for you as they are, provided that your digitizer
embeddedartists 0:0fdadbc3d852 658 * resolution does not exceed 10 bits (1024 values). Higher
embeddedartists 0:0fdadbc3d852 659 * resolutions may cause the integer operations to overflow
embeddedartists 0:0fdadbc3d852 660 * and return incorrect values. If you wish to use these
embeddedartists 0:0fdadbc3d852 661 * functions with digitizer resolutions of 12 bits (4096
embeddedartists 0:0fdadbc3d852 662 * values) you will either have to a) use 64-bit signed
embeddedartists 0:0fdadbc3d852 663 * integer variables and math, or b) judiciously modify the
embeddedartists 0:0fdadbc3d852 664 * operations to scale results by a factor of 2 or even 4.
embeddedartists 0:0fdadbc3d852 665 *
embeddedartists 0:0fdadbc3d852 666 *
embeddedartists 0:0fdadbc3d852 667 */
embeddedartists 0:0fdadbc3d852 668 int TSC2046::setCalibrationMatrix( calibPoint_t * displayPtr,
embeddedartists 0:0fdadbc3d852 669 calibPoint_t * screenPtr,
embeddedartists 0:0fdadbc3d852 670 calibMatrix_t * matrixPtr)
embeddedartists 0:0fdadbc3d852 671 {
embeddedartists 0:0fdadbc3d852 672 int retValue = 0 ;
embeddedartists 0:0fdadbc3d852 673
embeddedartists 0:0fdadbc3d852 674
embeddedartists 0:0fdadbc3d852 675 matrixPtr->Divider = ((screenPtr[0].x - screenPtr[2].x) * (screenPtr[1].y - screenPtr[2].y)) -
embeddedartists 0:0fdadbc3d852 676 ((screenPtr[1].x - screenPtr[2].x) * (screenPtr[0].y - screenPtr[2].y)) ;
embeddedartists 0:0fdadbc3d852 677 if( matrixPtr->Divider == 0 )
embeddedartists 0:0fdadbc3d852 678 {
embeddedartists 0:0fdadbc3d852 679 retValue = 1 ;
embeddedartists 0:0fdadbc3d852 680 }
embeddedartists 0:0fdadbc3d852 681 else
embeddedartists 0:0fdadbc3d852 682 {
embeddedartists 0:0fdadbc3d852 683 matrixPtr->An = ((displayPtr[0].x - displayPtr[2].x) * (screenPtr[1].y - screenPtr[2].y)) -
embeddedartists 0:0fdadbc3d852 684 ((displayPtr[1].x - displayPtr[2].x) * (screenPtr[0].y - screenPtr[2].y)) ;
embeddedartists 0:0fdadbc3d852 685 matrixPtr->Bn = ((screenPtr[0].x - screenPtr[2].x) * (displayPtr[1].x - displayPtr[2].x)) -
embeddedartists 0:0fdadbc3d852 686 ((displayPtr[0].x - displayPtr[2].x) * (screenPtr[1].x - screenPtr[2].x)) ;
embeddedartists 0:0fdadbc3d852 687 matrixPtr->Cn = (screenPtr[2].x * displayPtr[1].x - screenPtr[1].x * displayPtr[2].x) * screenPtr[0].y +
embeddedartists 0:0fdadbc3d852 688 (screenPtr[0].x * displayPtr[2].x - screenPtr[2].x * displayPtr[0].x) * screenPtr[1].y +
embeddedartists 0:0fdadbc3d852 689 (screenPtr[1].x * displayPtr[0].x - screenPtr[0].x * displayPtr[1].x) * screenPtr[2].y ;
embeddedartists 0:0fdadbc3d852 690 matrixPtr->Dn = ((displayPtr[0].y - displayPtr[2].y) * (screenPtr[1].y - screenPtr[2].y)) -
embeddedartists 0:0fdadbc3d852 691 ((displayPtr[1].y - displayPtr[2].y) * (screenPtr[0].y - screenPtr[2].y)) ;
embeddedartists 0:0fdadbc3d852 692
embeddedartists 0:0fdadbc3d852 693 matrixPtr->En = ((screenPtr[0].x - screenPtr[2].x) * (displayPtr[1].y - displayPtr[2].y)) -
embeddedartists 0:0fdadbc3d852 694 ((displayPtr[0].y - displayPtr[2].y) * (screenPtr[1].x - screenPtr[2].x)) ;
embeddedartists 0:0fdadbc3d852 695 matrixPtr->Fn = (screenPtr[2].x * displayPtr[1].y - screenPtr[1].x * displayPtr[2].y) * screenPtr[0].y +
embeddedartists 0:0fdadbc3d852 696 (screenPtr[0].x * displayPtr[2].y - screenPtr[2].x * displayPtr[0].y) * screenPtr[1].y +
embeddedartists 0:0fdadbc3d852 697 (screenPtr[1].x * displayPtr[0].y - screenPtr[0].x * displayPtr[1].y) * screenPtr[2].y ;
embeddedartists 0:0fdadbc3d852 698 }
embeddedartists 0:0fdadbc3d852 699
embeddedartists 0:0fdadbc3d852 700 return( retValue ) ;
embeddedartists 0:0fdadbc3d852 701 }
embeddedartists 0:0fdadbc3d852 702
embeddedartists 0:0fdadbc3d852 703 /**********************************************************************
embeddedartists 0:0fdadbc3d852 704 *
embeddedartists 0:0fdadbc3d852 705 * Function: getDisplayPoint()
embeddedartists 0:0fdadbc3d852 706 *
embeddedartists 0:0fdadbc3d852 707 * Description: Given a valid set of calibration factors and a point
embeddedartists 0:0fdadbc3d852 708 * value reported by the touch screen, this function
embeddedartists 0:0fdadbc3d852 709 * calculates and returns the true (or closest to true)
embeddedartists 0:0fdadbc3d852 710 * display point below the spot where the touch screen
embeddedartists 0:0fdadbc3d852 711 * was touched.
embeddedartists 0:0fdadbc3d852 712 *
embeddedartists 0:0fdadbc3d852 713 *
embeddedartists 0:0fdadbc3d852 714 *
embeddedartists 0:0fdadbc3d852 715 * Argument(s): displayPtr (output) - Pointer to the calculated
embeddedartists 0:0fdadbc3d852 716 * (true) display point.
embeddedartists 0:0fdadbc3d852 717 * screenPtr (input) - Pointer to the reported touch
embeddedartists 0:0fdadbc3d852 718 * screen point.
embeddedartists 0:0fdadbc3d852 719 * matrixPtr (input) - Pointer to calibration factors
embeddedartists 0:0fdadbc3d852 720 * matrix previously calculated
embeddedartists 0:0fdadbc3d852 721 * from a call to
embeddedartists 0:0fdadbc3d852 722 * setCalibrationMatrix()
embeddedartists 0:0fdadbc3d852 723 *
embeddedartists 0:0fdadbc3d852 724 *
embeddedartists 0:0fdadbc3d852 725 * The function simply solves for Xd and Yd by implementing the
embeddedartists 0:0fdadbc3d852 726 * computations required by the translation matrix.
embeddedartists 0:0fdadbc3d852 727 *
embeddedartists 0:0fdadbc3d852 728 * /- -\
embeddedartists 0:0fdadbc3d852 729 * /- -\ /- -\ | |
embeddedartists 0:0fdadbc3d852 730 * | | | | | Xs |
embeddedartists 0:0fdadbc3d852 731 * | Xd | | A B C | | |
embeddedartists 0:0fdadbc3d852 732 * | | = | | * | Ys |
embeddedartists 0:0fdadbc3d852 733 * | Yd | | D E F | | |
embeddedartists 0:0fdadbc3d852 734 * | | | | | 1 |
embeddedartists 0:0fdadbc3d852 735 * \- -/ \- -/ | |
embeddedartists 0:0fdadbc3d852 736 * \- -/
embeddedartists 0:0fdadbc3d852 737 *
embeddedartists 0:0fdadbc3d852 738 * It must be kept brief to avoid consuming CPU cycles.
embeddedartists 0:0fdadbc3d852 739 *
embeddedartists 0:0fdadbc3d852 740 *
embeddedartists 0:0fdadbc3d852 741 * Return: OK - the display point was correctly calculated
embeddedartists 0:0fdadbc3d852 742 * and its value is in the output argument.
embeddedartists 0:0fdadbc3d852 743 * NOT_OK - an error was detected and the function
embeddedartists 0:0fdadbc3d852 744 * failed to return a valid point.
embeddedartists 0:0fdadbc3d852 745 *
embeddedartists 0:0fdadbc3d852 746 *
embeddedartists 0:0fdadbc3d852 747 *
embeddedartists 0:0fdadbc3d852 748 * NOTE! NOTE! NOTE!
embeddedartists 0:0fdadbc3d852 749 *
embeddedartists 0:0fdadbc3d852 750 * setCalibrationMatrix() and getDisplayPoint() will do fine
embeddedartists 0:0fdadbc3d852 751 * for you as they are, provided that your digitizer
embeddedartists 0:0fdadbc3d852 752 * resolution does not exceed 10 bits (1024 values). Higher
embeddedartists 0:0fdadbc3d852 753 * resolutions may cause the integer operations to overflow
embeddedartists 0:0fdadbc3d852 754 * and return incorrect values. If you wish to use these
embeddedartists 0:0fdadbc3d852 755 * functions with digitizer resolutions of 12 bits (4096
embeddedartists 0:0fdadbc3d852 756 * values) you will either have to a) use 64-bit signed
embeddedartists 0:0fdadbc3d852 757 * integer variables and math, or b) judiciously modify the
embeddedartists 0:0fdadbc3d852 758 * operations to scale results by a factor of 2 or even 4.
embeddedartists 0:0fdadbc3d852 759 *
embeddedartists 0:0fdadbc3d852 760 *
embeddedartists 0:0fdadbc3d852 761 */
embeddedartists 0:0fdadbc3d852 762 int TSC2046::getDisplayPoint( calibPoint_t * displayPtr,
embeddedartists 0:0fdadbc3d852 763 calibPoint_t * screenPtr,
embeddedartists 0:0fdadbc3d852 764 calibMatrix_t * matrixPtr )
embeddedartists 0:0fdadbc3d852 765 {
embeddedartists 0:0fdadbc3d852 766 int retValue = 0 ;
embeddedartists 0:0fdadbc3d852 767
embeddedartists 0:0fdadbc3d852 768 if( matrixPtr->Divider != 0 )
embeddedartists 0:0fdadbc3d852 769 {
embeddedartists 0:0fdadbc3d852 770 /* Operation order is important since we are doing integer */
embeddedartists 0:0fdadbc3d852 771 /* math. Make sure you add all terms together before */
embeddedartists 0:0fdadbc3d852 772 /* dividing, so that the remainder is not rounded off */
embeddedartists 0:0fdadbc3d852 773 /* prematurely. */
embeddedartists 0:0fdadbc3d852 774 displayPtr->x = ( (matrixPtr->An * screenPtr->x) +
embeddedartists 0:0fdadbc3d852 775 (matrixPtr->Bn * screenPtr->y) +
embeddedartists 0:0fdadbc3d852 776 matrixPtr->Cn
embeddedartists 0:0fdadbc3d852 777 ) / matrixPtr->Divider ;
embeddedartists 0:0fdadbc3d852 778 displayPtr->y = ( (matrixPtr->Dn * screenPtr->x) +
embeddedartists 0:0fdadbc3d852 779 (matrixPtr->En * screenPtr->y) +
embeddedartists 0:0fdadbc3d852 780 matrixPtr->Fn
embeddedartists 0:0fdadbc3d852 781 ) / matrixPtr->Divider ;
embeddedartists 0:0fdadbc3d852 782 }
embeddedartists 0:0fdadbc3d852 783 else
embeddedartists 0:0fdadbc3d852 784 {
embeddedartists 0:0fdadbc3d852 785 retValue = 1 ;
embeddedartists 0:0fdadbc3d852 786 }
embeddedartists 0:0fdadbc3d852 787 return( retValue ) ;
embeddedartists 0:0fdadbc3d852 788 }
embeddedartists 0:0fdadbc3d852 789
embeddedartists 0:0fdadbc3d852 790
embeddedartists 4:b32cf4ef45c5 791
embeddedartists 0:0fdadbc3d852 792 // ############################################################################
embeddedartists 0:0fdadbc3d852 793 // <<<<<<<< Calibrate code <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
embeddedartists 0:0fdadbc3d852 794 // ############################################################################
embeddedartists 0:0fdadbc3d852 795
embeddedartists 0:0fdadbc3d852 796
embeddedartists 0:0fdadbc3d852 797