Library for MI0283QT-2 LCD

Committer:
clemente
Date:
Wed May 23 06:25:31 2012 +0000
Revision:
0:7ad454fed160

        

Who changed what in which revision?

UserRevisionLine numberNew contents of line
clemente 0:7ad454fed160 1 /*
clemente 0:7ad454fed160 2 *
clemente 0:7ad454fed160 3 * Copyright (c) 2001, Carlos E. Vidales. All rights reserved.
clemente 0:7ad454fed160 4 *
clemente 0:7ad454fed160 5 * This sample program was written and put in the public domain
clemente 0:7ad454fed160 6 * by Carlos E. Vidales. The program is provided "as is"
clemente 0:7ad454fed160 7 * without warranty of any kind, either expressed or implied.
clemente 0:7ad454fed160 8 * If you choose to use the program within your own products
clemente 0:7ad454fed160 9 * you do so at your own risk, and assume the responsibility
clemente 0:7ad454fed160 10 * for servicing, repairing or correcting the program should
clemente 0:7ad454fed160 11 * it prove defective in any manner.
clemente 0:7ad454fed160 12 * You may copy and distribute the program's source code in any
clemente 0:7ad454fed160 13 * medium, provided that you also include in each copy an
clemente 0:7ad454fed160 14 * appropriate copyright notice and disclaimer of warranty.
clemente 0:7ad454fed160 15 * You may also modify this program and distribute copies of
clemente 0:7ad454fed160 16 * it provided that you include prominent notices stating
clemente 0:7ad454fed160 17 * that you changed the file(s) and the date of any change,
clemente 0:7ad454fed160 18 * and that you do not charge any royalties or licenses for
clemente 0:7ad454fed160 19 * its use.
clemente 0:7ad454fed160 20 *
clemente 0:7ad454fed160 21 *
clemente 0:7ad454fed160 22 *
clemente 0:7ad454fed160 23 * File Name: calibrate.c
clemente 0:7ad454fed160 24 *
clemente 0:7ad454fed160 25 *
clemente 0:7ad454fed160 26 * This file contains functions that implement calculations
clemente 0:7ad454fed160 27 * necessary to obtain calibration factors for a touch screen
clemente 0:7ad454fed160 28 * that suffers from multiple distortion effects: namely,
clemente 0:7ad454fed160 29 * translation, scaling and rotation.
clemente 0:7ad454fed160 30 *
clemente 0:7ad454fed160 31 * The following set of equations represent a valid display
clemente 0:7ad454fed160 32 * point given a corresponding set of touch screen points:
clemente 0:7ad454fed160 33 *
clemente 0:7ad454fed160 34 *
clemente 0:7ad454fed160 35 * /- -\
clemente 0:7ad454fed160 36 * /- -\ /- -\ | |
clemente 0:7ad454fed160 37 * | | | | | Xs |
clemente 0:7ad454fed160 38 * | Xd | | A B C | | |
clemente 0:7ad454fed160 39 * | | = | | * | Ys |
clemente 0:7ad454fed160 40 * | Yd | | D E F | | |
clemente 0:7ad454fed160 41 * | | | | | 1 |
clemente 0:7ad454fed160 42 * \- -/ \- -/ | |
clemente 0:7ad454fed160 43 * \- -/
clemente 0:7ad454fed160 44 *
clemente 0:7ad454fed160 45 *
clemente 0:7ad454fed160 46 * where:
clemente 0:7ad454fed160 47 *
clemente 0:7ad454fed160 48 * (Xd,Yd) represents the desired display point
clemente 0:7ad454fed160 49 * coordinates,
clemente 0:7ad454fed160 50 *
clemente 0:7ad454fed160 51 * (Xs,Ys) represents the available touch screen
clemente 0:7ad454fed160 52 * coordinates, and the matrix
clemente 0:7ad454fed160 53 *
clemente 0:7ad454fed160 54 * /- -\
clemente 0:7ad454fed160 55 * |A,B,C|
clemente 0:7ad454fed160 56 * |D,E,F| represents the factors used to translate
clemente 0:7ad454fed160 57 * \- -/ the available touch screen point values
clemente 0:7ad454fed160 58 * into the corresponding display
clemente 0:7ad454fed160 59 * coordinates.
clemente 0:7ad454fed160 60 *
clemente 0:7ad454fed160 61 *
clemente 0:7ad454fed160 62 * Note that for practical considerations, the utilitities
clemente 0:7ad454fed160 63 * within this file do not use the matrix coefficients as
clemente 0:7ad454fed160 64 * defined above, but instead use the following
clemente 0:7ad454fed160 65 * equivalents, since floating point math is not used:
clemente 0:7ad454fed160 66 *
clemente 0:7ad454fed160 67 * A = An/Divider
clemente 0:7ad454fed160 68 * B = Bn/Divider
clemente 0:7ad454fed160 69 * C = Cn/Divider
clemente 0:7ad454fed160 70 * D = Dn/Divider
clemente 0:7ad454fed160 71 * E = En/Divider
clemente 0:7ad454fed160 72 * F = Fn/Divider
clemente 0:7ad454fed160 73 *
clemente 0:7ad454fed160 74 *
clemente 0:7ad454fed160 75 *
clemente 0:7ad454fed160 76 * The functions provided within this file are:
clemente 0:7ad454fed160 77 *
clemente 0:7ad454fed160 78 * setCalibrationMatrix() - calculates the set of factors
clemente 0:7ad454fed160 79 * in the above equation, given
clemente 0:7ad454fed160 80 * three sets of test points.
clemente 0:7ad454fed160 81 * getDisplayPoint() - returns the actual display
clemente 0:7ad454fed160 82 * coordinates, given a set of
clemente 0:7ad454fed160 83 * touch screen coordinates.
clemente 0:7ad454fed160 84 * translateRawScreenCoordinates() - helper function to transform
clemente 0:7ad454fed160 85 * raw screen points into values
clemente 0:7ad454fed160 86 * scaled to the desired display
clemente 0:7ad454fed160 87 * resolution.
clemente 0:7ad454fed160 88 *
clemente 0:7ad454fed160 89 *
clemente 0:7ad454fed160 90 */
clemente 0:7ad454fed160 91
clemente 0:7ad454fed160 92
clemente 0:7ad454fed160 93 #define _CALIBRATE_C_
clemente 0:7ad454fed160 94
clemente 0:7ad454fed160 95
clemente 0:7ad454fed160 96
clemente 0:7ad454fed160 97 /****************************************************/
clemente 0:7ad454fed160 98 /* */
clemente 0:7ad454fed160 99 /* Included files */
clemente 0:7ad454fed160 100 /* */
clemente 0:7ad454fed160 101 /****************************************************/
clemente 0:7ad454fed160 102
clemente 0:7ad454fed160 103 #include "calibrate.h"
clemente 0:7ad454fed160 104
clemente 0:7ad454fed160 105
clemente 0:7ad454fed160 106
clemente 0:7ad454fed160 107 /****************************************************/
clemente 0:7ad454fed160 108 /* */
clemente 0:7ad454fed160 109 /* Local Definitions and macros */
clemente 0:7ad454fed160 110 /* */
clemente 0:7ad454fed160 111 /****************************************************/
clemente 0:7ad454fed160 112
clemente 0:7ad454fed160 113
clemente 0:7ad454fed160 114
clemente 0:7ad454fed160 115 /****************************************************/
clemente 0:7ad454fed160 116 /* */
clemente 0:7ad454fed160 117 /* Global variables */
clemente 0:7ad454fed160 118 /* */
clemente 0:7ad454fed160 119 /****************************************************/
clemente 0:7ad454fed160 120
clemente 0:7ad454fed160 121
clemente 0:7ad454fed160 122
clemente 0:7ad454fed160 123 /****************************************************/
clemente 0:7ad454fed160 124 /* */
clemente 0:7ad454fed160 125 /* Forward Declaration of local functions */
clemente 0:7ad454fed160 126 /* */
clemente 0:7ad454fed160 127 /****************************************************/
clemente 0:7ad454fed160 128
clemente 0:7ad454fed160 129
clemente 0:7ad454fed160 130
clemente 0:7ad454fed160 131
clemente 0:7ad454fed160 132
clemente 0:7ad454fed160 133
clemente 0:7ad454fed160 134 /**********************************************************************
clemente 0:7ad454fed160 135 *
clemente 0:7ad454fed160 136 * Function: setCalibrationMatrix()
clemente 0:7ad454fed160 137 *
clemente 0:7ad454fed160 138 * Description: Calling this function with valid input data
clemente 0:7ad454fed160 139 * in the display and screen input arguments
clemente 0:7ad454fed160 140 * causes the calibration factors between the
clemente 0:7ad454fed160 141 * screen and display points to be calculated,
clemente 0:7ad454fed160 142 * and the output argument - matrixPtr - to be
clemente 0:7ad454fed160 143 * populated.
clemente 0:7ad454fed160 144 *
clemente 0:7ad454fed160 145 * This function needs to be called only when new
clemente 0:7ad454fed160 146 * calibration factors are desired.
clemente 0:7ad454fed160 147 *
clemente 0:7ad454fed160 148 *
clemente 0:7ad454fed160 149 * Argument(s): displayPtr (input) - Pointer to an array of three
clemente 0:7ad454fed160 150 * sample, reference points.
clemente 0:7ad454fed160 151 * screenPtr (input) - Pointer to the array of touch
clemente 0:7ad454fed160 152 * screen points corresponding
clemente 0:7ad454fed160 153 * to the reference display points.
clemente 0:7ad454fed160 154 * matrixPtr (output) - Pointer to the calibration
clemente 0:7ad454fed160 155 * matrix computed for the set
clemente 0:7ad454fed160 156 * of points being provided.
clemente 0:7ad454fed160 157 *
clemente 0:7ad454fed160 158 *
clemente 0:7ad454fed160 159 * From the article text, recall that the matrix coefficients are
clemente 0:7ad454fed160 160 * resolved to be the following:
clemente 0:7ad454fed160 161 *
clemente 0:7ad454fed160 162 *
clemente 0:7ad454fed160 163 * Divider = (Xs0 - Xs2)*(Ys1 - Ys2) - (Xs1 - Xs2)*(Ys0 - Ys2)
clemente 0:7ad454fed160 164 *
clemente 0:7ad454fed160 165 *
clemente 0:7ad454fed160 166 *
clemente 0:7ad454fed160 167 * (Xd0 - Xd2)*(Ys1 - Ys2) - (Xd1 - Xd2)*(Ys0 - Ys2)
clemente 0:7ad454fed160 168 * A = ---------------------------------------------------
clemente 0:7ad454fed160 169 * Divider
clemente 0:7ad454fed160 170 *
clemente 0:7ad454fed160 171 *
clemente 0:7ad454fed160 172 * (Xs0 - Xs2)*(Xd1 - Xd2) - (Xd0 - Xd2)*(Xs1 - Xs2)
clemente 0:7ad454fed160 173 * B = ---------------------------------------------------
clemente 0:7ad454fed160 174 * Divider
clemente 0:7ad454fed160 175 *
clemente 0:7ad454fed160 176 *
clemente 0:7ad454fed160 177 * Ys0*(Xs2*Xd1 - Xs1*Xd2) +
clemente 0:7ad454fed160 178 * Ys1*(Xs0*Xd2 - Xs2*Xd0) +
clemente 0:7ad454fed160 179 * Ys2*(Xs1*Xd0 - Xs0*Xd1)
clemente 0:7ad454fed160 180 * C = ---------------------------------------------------
clemente 0:7ad454fed160 181 * Divider
clemente 0:7ad454fed160 182 *
clemente 0:7ad454fed160 183 *
clemente 0:7ad454fed160 184 * (Yd0 - Yd2)*(Ys1 - Ys2) - (Yd1 - Yd2)*(Ys0 - Ys2)
clemente 0:7ad454fed160 185 * D = ---------------------------------------------------
clemente 0:7ad454fed160 186 * Divider
clemente 0:7ad454fed160 187 *
clemente 0:7ad454fed160 188 *
clemente 0:7ad454fed160 189 * (Xs0 - Xs2)*(Yd1 - Yd2) - (Yd0 - Yd2)*(Xs1 - Xs2)
clemente 0:7ad454fed160 190 * E = ---------------------------------------------------
clemente 0:7ad454fed160 191 * Divider
clemente 0:7ad454fed160 192 *
clemente 0:7ad454fed160 193 *
clemente 0:7ad454fed160 194 * Ys0*(Xs2*Yd1 - Xs1*Yd2) +
clemente 0:7ad454fed160 195 * Ys1*(Xs0*Yd2 - Xs2*Yd0) +
clemente 0:7ad454fed160 196 * Ys2*(Xs1*Yd0 - Xs0*Yd1)
clemente 0:7ad454fed160 197 * F = ---------------------------------------------------
clemente 0:7ad454fed160 198 * Divider
clemente 0:7ad454fed160 199 *
clemente 0:7ad454fed160 200 *
clemente 0:7ad454fed160 201 * Return: OK - the calibration matrix was correctly
clemente 0:7ad454fed160 202 * calculated and its value is in the
clemente 0:7ad454fed160 203 * output argument.
clemente 0:7ad454fed160 204 * NOT_OK - an error was detected and the
clemente 0:7ad454fed160 205 * function failed to return a valid
clemente 0:7ad454fed160 206 * set of matrix values.
clemente 0:7ad454fed160 207 * The only time this sample code returns
clemente 0:7ad454fed160 208 * NOT_OK is when Divider == 0
clemente 0:7ad454fed160 209 *
clemente 0:7ad454fed160 210 *
clemente 0:7ad454fed160 211 *
clemente 0:7ad454fed160 212 * NOTE! NOTE! NOTE!
clemente 0:7ad454fed160 213 *
clemente 0:7ad454fed160 214 * setCalibrationMatrix() and getDisplayPoint() will do fine
clemente 0:7ad454fed160 215 * for you as they are, provided that your digitizer
clemente 0:7ad454fed160 216 * resolution does not exceed 10 bits (1024 values). Higher
clemente 0:7ad454fed160 217 * resolutions may cause the integer operations to overflow
clemente 0:7ad454fed160 218 * and return incorrect values. If you wish to use these
clemente 0:7ad454fed160 219 * functions with digitizer resolutions of 12 bits (4096
clemente 0:7ad454fed160 220 * values) you will either have to a) use 64-bit signed
clemente 0:7ad454fed160 221 * integer variables and math, or b) judiciously modify the
clemente 0:7ad454fed160 222 * operations to scale results by a factor of 2 or even 4.
clemente 0:7ad454fed160 223 *
clemente 0:7ad454fed160 224 *
clemente 0:7ad454fed160 225 */
clemente 0:7ad454fed160 226 unsigned char setCalibrationMatrix( POINT * displayPtr,
clemente 0:7ad454fed160 227 POINT * screenPtr,
clemente 0:7ad454fed160 228 MATRIX * matrixPtr)
clemente 0:7ad454fed160 229 {
clemente 0:7ad454fed160 230
clemente 0:7ad454fed160 231 unsigned char retValue = OK ;
clemente 0:7ad454fed160 232
clemente 0:7ad454fed160 233
clemente 0:7ad454fed160 234
clemente 0:7ad454fed160 235 matrixPtr->Divider = ((screenPtr[0].x - screenPtr[2].x) * (screenPtr[1].y - screenPtr[2].y)) -
clemente 0:7ad454fed160 236 ((screenPtr[1].x - screenPtr[2].x) * (screenPtr[0].y - screenPtr[2].y)) ;
clemente 0:7ad454fed160 237
clemente 0:7ad454fed160 238 if( matrixPtr->Divider == 0 )
clemente 0:7ad454fed160 239 {
clemente 0:7ad454fed160 240 retValue = NOT_OK ;
clemente 0:7ad454fed160 241 }
clemente 0:7ad454fed160 242 else
clemente 0:7ad454fed160 243 {
clemente 0:7ad454fed160 244 matrixPtr->An = ((displayPtr[0].x - displayPtr[2].x) * (screenPtr[1].y - screenPtr[2].y)) -
clemente 0:7ad454fed160 245 ((displayPtr[1].x - displayPtr[2].x) * (screenPtr[0].y - screenPtr[2].y)) ;
clemente 0:7ad454fed160 246
clemente 0:7ad454fed160 247 matrixPtr->Bn = ((screenPtr[0].x - screenPtr[2].x) * (displayPtr[1].x - displayPtr[2].x)) -
clemente 0:7ad454fed160 248 ((displayPtr[0].x - displayPtr[2].x) * (screenPtr[1].x - screenPtr[2].x)) ;
clemente 0:7ad454fed160 249
clemente 0:7ad454fed160 250 matrixPtr->Cn = (screenPtr[2].x * displayPtr[1].x - screenPtr[1].x * displayPtr[2].x) * screenPtr[0].y +
clemente 0:7ad454fed160 251 (screenPtr[0].x * displayPtr[2].x - screenPtr[2].x * displayPtr[0].x) * screenPtr[1].y +
clemente 0:7ad454fed160 252 (screenPtr[1].x * displayPtr[0].x - screenPtr[0].x * displayPtr[1].x) * screenPtr[2].y ;
clemente 0:7ad454fed160 253
clemente 0:7ad454fed160 254 matrixPtr->Dn = ((displayPtr[0].y - displayPtr[2].y) * (screenPtr[1].y - screenPtr[2].y)) -
clemente 0:7ad454fed160 255 ((displayPtr[1].y - displayPtr[2].y) * (screenPtr[0].y - screenPtr[2].y)) ;
clemente 0:7ad454fed160 256
clemente 0:7ad454fed160 257 matrixPtr->En = ((screenPtr[0].x - screenPtr[2].x) * (displayPtr[1].y - displayPtr[2].y)) -
clemente 0:7ad454fed160 258 ((displayPtr[0].y - displayPtr[2].y) * (screenPtr[1].x - screenPtr[2].x)) ;
clemente 0:7ad454fed160 259
clemente 0:7ad454fed160 260 matrixPtr->Fn = (screenPtr[2].x * displayPtr[1].y - screenPtr[1].x * displayPtr[2].y) * screenPtr[0].y +
clemente 0:7ad454fed160 261 (screenPtr[0].x * displayPtr[2].y - screenPtr[2].x * displayPtr[0].y) * screenPtr[1].y +
clemente 0:7ad454fed160 262 (screenPtr[1].x * displayPtr[0].y - screenPtr[0].x * displayPtr[1].y) * screenPtr[2].y ;
clemente 0:7ad454fed160 263 }
clemente 0:7ad454fed160 264
clemente 0:7ad454fed160 265 return( retValue ) ;
clemente 0:7ad454fed160 266
clemente 0:7ad454fed160 267 } /* end of setCalibrationMatrix() */
clemente 0:7ad454fed160 268
clemente 0:7ad454fed160 269
clemente 0:7ad454fed160 270
clemente 0:7ad454fed160 271 /**********************************************************************
clemente 0:7ad454fed160 272 *
clemente 0:7ad454fed160 273 * Function: getDisplayPoint()
clemente 0:7ad454fed160 274 *
clemente 0:7ad454fed160 275 * Description: Given a valid set of calibration factors and a point
clemente 0:7ad454fed160 276 * value reported by the touch screen, this function
clemente 0:7ad454fed160 277 * calculates and returns the true (or closest to true)
clemente 0:7ad454fed160 278 * display point below the spot where the touch screen
clemente 0:7ad454fed160 279 * was touched.
clemente 0:7ad454fed160 280 *
clemente 0:7ad454fed160 281 *
clemente 0:7ad454fed160 282 *
clemente 0:7ad454fed160 283 * Argument(s): displayPtr (output) - Pointer to the calculated
clemente 0:7ad454fed160 284 * (true) display point.
clemente 0:7ad454fed160 285 * screenPtr (input) - Pointer to the reported touch
clemente 0:7ad454fed160 286 * screen point.
clemente 0:7ad454fed160 287 * matrixPtr (input) - Pointer to calibration factors
clemente 0:7ad454fed160 288 * matrix previously calculated
clemente 0:7ad454fed160 289 * from a call to
clemente 0:7ad454fed160 290 * setCalibrationMatrix()
clemente 0:7ad454fed160 291 *
clemente 0:7ad454fed160 292 *
clemente 0:7ad454fed160 293 * The function simply solves for Xd and Yd by implementing the
clemente 0:7ad454fed160 294 * computations required by the translation matrix.
clemente 0:7ad454fed160 295 *
clemente 0:7ad454fed160 296 * /- -\
clemente 0:7ad454fed160 297 * /- -\ /- -\ | |
clemente 0:7ad454fed160 298 * | | | | | Xs |
clemente 0:7ad454fed160 299 * | Xd | | A B C | | |
clemente 0:7ad454fed160 300 * | | = | | * | Ys |
clemente 0:7ad454fed160 301 * | Yd | | D E F | | |
clemente 0:7ad454fed160 302 * | | | | | 1 |
clemente 0:7ad454fed160 303 * \- -/ \- -/ | |
clemente 0:7ad454fed160 304 * \- -/
clemente 0:7ad454fed160 305 *
clemente 0:7ad454fed160 306 * It must be kept brief to avoid consuming CPU cycles.
clemente 0:7ad454fed160 307 *
clemente 0:7ad454fed160 308 *
clemente 0:7ad454fed160 309 * Return: OK - the display point was correctly calculated
clemente 0:7ad454fed160 310 * and its value is in the output argument.
clemente 0:7ad454fed160 311 * NOT_OK - an error was detected and the function
clemente 0:7ad454fed160 312 * failed to return a valid point.
clemente 0:7ad454fed160 313 *
clemente 0:7ad454fed160 314 *
clemente 0:7ad454fed160 315 *
clemente 0:7ad454fed160 316 * NOTE! NOTE! NOTE!
clemente 0:7ad454fed160 317 *
clemente 0:7ad454fed160 318 * setCalibrationMatrix() and getDisplayPoint() will do fine
clemente 0:7ad454fed160 319 * for you as they are, provided that your digitizer
clemente 0:7ad454fed160 320 * resolution does not exceed 10 bits (1024 values). Higher
clemente 0:7ad454fed160 321 * resolutions may cause the integer operations to overflow
clemente 0:7ad454fed160 322 * and return incorrect values. If you wish to use these
clemente 0:7ad454fed160 323 * functions with digitizer resolutions of 12 bits (4096
clemente 0:7ad454fed160 324 * values) you will either have to a) use 64-bit signed
clemente 0:7ad454fed160 325 * integer variables and math, or b) judiciously modify the
clemente 0:7ad454fed160 326 * operations to scale results by a factor of 2 or even 4.
clemente 0:7ad454fed160 327 *
clemente 0:7ad454fed160 328 *
clemente 0:7ad454fed160 329 */
clemente 0:7ad454fed160 330 unsigned char getDisplayPoint( POINT * displayPtr,
clemente 0:7ad454fed160 331 POINT * screenPtr,
clemente 0:7ad454fed160 332 MATRIX * matrixPtr )
clemente 0:7ad454fed160 333 {
clemente 0:7ad454fed160 334 unsigned char retValue = OK ;
clemente 0:7ad454fed160 335
clemente 0:7ad454fed160 336
clemente 0:7ad454fed160 337 if( matrixPtr->Divider != 0 )
clemente 0:7ad454fed160 338 {
clemente 0:7ad454fed160 339
clemente 0:7ad454fed160 340 /* Operation order is important since we are doing integer */
clemente 0:7ad454fed160 341 /* math. Make sure you add all terms together before */
clemente 0:7ad454fed160 342 /* dividing, so that the remainder is not rounded off */
clemente 0:7ad454fed160 343 /* prematurely. */
clemente 0:7ad454fed160 344
clemente 0:7ad454fed160 345 displayPtr->x = ( (matrixPtr->An * screenPtr->x) +
clemente 0:7ad454fed160 346 (matrixPtr->Bn * screenPtr->y) +
clemente 0:7ad454fed160 347 matrixPtr->Cn
clemente 0:7ad454fed160 348 ) / matrixPtr->Divider ;
clemente 0:7ad454fed160 349
clemente 0:7ad454fed160 350 displayPtr->y = ( (matrixPtr->Dn * screenPtr->x) +
clemente 0:7ad454fed160 351 (matrixPtr->En * screenPtr->y) +
clemente 0:7ad454fed160 352 matrixPtr->Fn
clemente 0:7ad454fed160 353 ) / matrixPtr->Divider ;
clemente 0:7ad454fed160 354 }
clemente 0:7ad454fed160 355 else
clemente 0:7ad454fed160 356 {
clemente 0:7ad454fed160 357 retValue = NOT_OK ;
clemente 0:7ad454fed160 358 }
clemente 0:7ad454fed160 359
clemente 0:7ad454fed160 360 return( retValue ) ;
clemente 0:7ad454fed160 361
clemente 0:7ad454fed160 362 } /* end of getDisplayPoint() */
clemente 0:7ad454fed160 363