2 * tslib/tests/ts_calibrate.c
4 * Copyright (C) 2001 Russell King.
6 * This file is placed under the GPL. Please see the file
7 * COPYING for more details.
9 * $Id: ts_calibrate.c,v 1.8 2004/10/19 22:01:27 dlowder Exp $
11 * Basic test program for touchscreen library.
20 #include <sys/fcntl.h>
21 #include <sys/ioctl.h>
32 #include "testutils.h"
34 static int palette [] =
36 0x000000, 0xffe080, 0xffffff, 0xe0c0a0
38 #define NR_COLORS (sizeof (palette) / sizeof (palette [0]))
46 static void sig(int sig)
50 printf ("signal %d caught\n", sig);
55 int perform_calibration(calibration *cal) {
57 float n, x, y, x2, y2, xy, z, zx, zy;
58 float det, a, b, c, e, f, i;
59 float scaling = 65536.0;
61 // Get sums for matrix
62 n = x = y = x2 = y2 = xy = 0;
65 x += (float)cal->x[j];
66 y += (float)cal->y[j];
67 x2 += (float)(cal->x[j]*cal->x[j]);
68 y2 += (float)(cal->y[j]*cal->y[j]);
69 xy += (float)(cal->x[j]*cal->y[j]);
72 // Get determinant of matrix -- check if determinant is too small
73 det = n*(x2*y2 - xy*xy) + x*(xy*y - x*y2) + y*(x*xy - y*x2);
74 if(det < 0.1 && det > -0.1) {
75 printf("ts_calibrate: determinant is too small -- %f\n",det);
79 // Get elements of inverse matrix
80 a = (x2*y2 - xy*xy)/det;
81 b = (xy*y - x*y2)/det;
82 c = (x*xy - y*x2)/det;
87 // Get sums for x calibration
90 z += (float)cal->xfb[j];
91 zx += (float)(cal->xfb[j]*cal->x[j]);
92 zy += (float)(cal->xfb[j]*cal->y[j]);
95 // Now multiply out to get the calibration for framebuffer x coord
96 cal->a[0] = (int)((a*z + b*zx + c*zy)*(scaling));
97 cal->a[1] = (int)((b*z + e*zx + f*zy)*(scaling));
98 cal->a[2] = (int)((c*z + f*zx + i*zy)*(scaling));
100 printf("%f %f %f\n",(a*z + b*zx + c*zy),
102 (c*z + f*zx + i*zy));
104 // Get sums for y calibration
107 z += (float)cal->yfb[j];
108 zx += (float)(cal->yfb[j]*cal->x[j]);
109 zy += (float)(cal->yfb[j]*cal->y[j]);
112 // Now multiply out to get the calibration for framebuffer y coord
113 cal->a[3] = (int)((a*z + b*zx + c*zy)*(scaling));
114 cal->a[4] = (int)((b*z + e*zx + f*zy)*(scaling));
115 cal->a[5] = (int)((c*z + f*zx + i*zy)*(scaling));
117 printf("%f %f %f\n",(a*z + b*zx + c*zy),
119 (c*z + f*zx + i*zy));
121 // If we got here, we're OK, so assign scaling to a[6] and return
122 cal->a[6] = (int)scaling;
125 // This code was here originally to just insert default values
129 c->a[1] = c->a[5] = c->a[6] = 1;
135 static void get_sample (struct tsdev *ts, calibration *cal,
136 int index, int x, int y, char *name)
138 static int last_x = -1, last_y;
142 int dx = ((x - last_x) << 16) / NR_STEPS;
143 int dy = ((y - last_y) << 16) / NR_STEPS;
147 for (i = 0; i < NR_STEPS; i++) {
148 put_cross (last_x >> 16, last_y >> 16, 2 | XORMODE);
150 put_cross (last_x >> 16, last_y >> 16, 2 | XORMODE);
156 put_cross(x, y, 2 | XORMODE);
157 getxy (ts, &cal->x [index], &cal->y [index]);
158 put_cross(x, y, 2 | XORMODE);
160 last_x = cal->xfb [index] = x;
161 last_y = cal->yfb [index] = y;
163 printf("%s : X = %4d Y = %4d\n", name, cal->x [index], cal->y [index]);
166 static int clearbuf(struct tsdev *ts)
172 struct ts_sample sample;
181 nfds = select(fd + 1, &fdset, NULL, NULL, &tv);
182 if (nfds == 0) break;
184 if (ts_read_raw(ts, &sample, 1) < 0) {
196 char cal_buffer[256];
197 char *tsdevice = NULL;
198 char *calfile = NULL;
201 signal(SIGSEGV, sig);
203 signal(SIGTERM, sig);
205 if( (tsdevice = getenv("TSLIB_TSDEVICE")) != NULL ) {
206 ts = ts_open(tsdevice,0);
208 if (!(ts = ts_open("/dev/input/event0", 0)))
209 ts = ts_open("/dev/touchscreen/ucb1x00", 0);
221 if (open_framebuffer()) {
226 for (i = 0; i < NR_COLORS; i++)
227 setcolor (i, palette [i]);
229 put_string_center (xres / 2, yres / 4,
230 "TSLIB calibration utility", 1);
231 put_string_center (xres / 2, yres / 4 + 20,
232 "Touch crosshair to calibrate", 2);
234 printf("xres = %d, yres = %d\n", xres, yres);
239 get_sample (ts, &cal, 0, 50, 50, "Top left");
241 get_sample (ts, &cal, 1, xres - 50, 50, "Top right");
243 get_sample (ts, &cal, 2, xres - 50, yres - 50, "Bot right");
245 get_sample (ts, &cal, 3, 50, yres - 50, "Bot left");
247 get_sample (ts, &cal, 4, xres / 2, yres / 2, "Center");
249 if (perform_calibration (&cal)) {
250 printf ("Calibration constants: ");
251 for (i = 0; i < 7; i++) printf("%d ", cal.a [i]);
253 if ((calfile = getenv("TSLIB_CALIBFILE")) != NULL) {
254 cal_fd = open (calfile, O_CREAT | O_RDWR,
255 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
257 cal_fd = open (TS_POINTERCAL, O_CREAT | O_RDWR,
258 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
260 sprintf (cal_buffer,"%d %d %d %d %d %d %d",
261 cal.a[1], cal.a[2], cal.a[0],
262 cal.a[4], cal.a[5], cal.a[3], cal.a[6]);
263 write (cal_fd, cal_buffer, strlen (cal_buffer) + 1);
267 printf("Calibration failed.\n");