The wait in mci_WaitForEvent will delay all card transactions.
Fork of EALib by
TSC2046.cpp@6:405c6e5a4eaf, 2013-10-31 (annotated)
- Committer:
- embeddedartists
- Date:
- Thu Oct 31 13:23:11 2013 +0000
- Revision:
- 6:405c6e5a4eaf
- Parent:
- 4:b32cf4ef45c5
Updated SPI clock frequency for TSC2046
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 | 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 |