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