/* Allen Cheng. 2000/6/20 */ #include #include #include #include #include #include #include #include #include #include #include #include #include "touch.h" /* This program is for the calibration of the touchscreen. Because the signal of the touchscreen is analog, the demo board of the Assabet is using the UCB1300 to convert the signal of the touchscreen from analog to digital. We get the data from the touchscreen driver is just the data of the A/D converter of the UCB1300. Thus, we have to convert the data of the A/D converter to the real X,Y coordination. We plot 5 black-crosses at the LCD screen.The sequence is from (1) to (5), the relation is plot at Fig.1. We get the 5-point data of the A/D converter of the UCB1300 and determine these data is right or not. And we calculate the relationship between the data of the A/D converter of the UCB1300 and the real X,Y coordination. According to the relationship,we can get the real X,Y coordination when user touches any point of the the touchscreen. Y-axis <-- (0,0) +---------------------------+ | (3) (2) | | | + + | | |(40,200) (40,40) | \/ | | X-axis | | | (1) | | + | | (160,120) | | | | | | (4) (5) | | + + | |(280,200) (280,40) | | | +---------------------------+ (320,240) +---+ +---+(RS232 Cable connector) ( Fig. 1 ) The other part of this program is draw a mini-keyboard at the LCD. Whe user touches the key of the mini-keyboard */ #define ERROR 9 #define ERROR_RATE 16 #define SCREEN_WIDTH 320 #define SCREEN_HEIGHT 240 #define SZ_XHAIR 50 #define X1 40 #define Y1 40 #define X2 280 #define Y2 200 #define LEN 10 #define Xm 160 #define Ym 120 #define step 20 #define Points 5 #define Xdef1 (Xm-X1)/step #define Ydef1 (Ym-Y1)/step #define Xdef2 (X2-X1)/step #define Ydef2 (Y2-Y1)/step #define DEV_NODE "/dev/ts" typedef struct { short p; short x; short y; short pad; }TS_DATA; /* PhantomCat, defined by allen */ typedef struct { int enable; int x_max; /* offset for x pos */ int y_max; int p_max; int x_min; /* offset for x pos */ int y_min; int p_min; int x_pd; /* offset for x pos */ int y_pd; int p_pd; int penup; int buf_clr; }CAL_T; /* PhantomCat */ int dev_no, get_points; int no,i,j,Xsum,Ysum,touch_ok; int Xd,Yd,XX,YY; float Xp1,Xp2,Yp1,Yp2; float Xpd,Ypd; int XXmin,XXmax,YYmin,YYmax; int Xavg[5],Yavg[5]; TS_DATA p; CAL_T cal_t; /* X globals */ Display *dpy; Window w; GC gc; int blackColor, whiteColor; #define NIL (0) void do_calibration(void); void get_XYmax(void); void getXY_b(void); void getXY_a(void); int dev_open(void); int dev_close(void); int dev_dis(void); int dev_setall(void); int dev_getall(void); int dev_buf_clr(void); int dev_penup(void); int dev_read(void); void perro(int Xr,int Yr); void print_par(void); int ts_buf_clr(void); void penup_check(void); void delay_time(int x,int y); int initX(void); static void drawPlus (int xcoord, int ycoord,int delete); void main() { int count; touch_ok = 0; printf("Welcome\n"); if ( initX() < 0 ) { printf("Unable to Xinit\n"); exit(1); } printf("init X ok\n"); if (dev_open()==ERROR) return; if (dev_dis()==ERROR) return; while (!touch_ok) { do_calibration(); get_XYmax(); } if (dev_setall()==ERROR) return; printf("Calibration OK!\n\n"); penup_check(); for (count = 0; count <= 20; count++) { printf("\n Point-%2d -- ",count); getXY_a(); } if (dev_close()==ERROR) return; } void delay_time(int x,int y) { for (i=0;i<=x;i++) for (j=0;j<=y;j++); return; } void penup_check(void) { do { if (dev_penup()==ERROR) return; delay_time(255,255); }while(!cal_t.penup); if (ts_buf_clr()==ERROR) return; return; } void do_calibration(void) { for (no = 0 ; no < 5 ; no++ ) { Xavg[no] = 0; Yavg[no] = 0; get_points = 0; switch (no) { case 0 : printf("\nTouch screen at x=%d y=%d\n",Xm,Ym); drawPlus(Xm, Ym,0); break; case 1 : printf("\nTouch screen at x=%d y=%d\n",X1,Y1); drawPlus(X1, Y1,0); break; case 2 : printf("\nTouch screen at x=%d y=%d\n",X1,Y2); drawPlus(X1, Y2,0); break; case 3 : printf("\nTouch screen at x=%d y=%d\n",X2,Y2); drawPlus(X2, Y2,0); break; case 4 : printf("\nTouch screen at x=%d y=%d\n",X2,Y1); drawPlus(X2, Y1,0); break; } do { if (dev_read()==ERROR) return; else if (get_points <= Points) { Xavg[no] += p.x; Yavg[no] += p.y; get_points++; } else break; if (dev_penup()==ERROR) return; }while((!cal_t.penup)||(get_points <= Points)); penup_check(); Xavg[no] = Xavg[no]/get_points; Yavg[no] = Yavg[no]/get_points; printf("\n Point - %d : Xavg = %d ; Yavg = %d\n",no,Xavg[no],Yavg[no]); for (i = 0 ; i < step ; i++) { switch (no) { case 0 : drawPlus((Xm - i*Xdef1), (Ym - i*Ydef1),1); drawPlus((Xm - (i+1)*Xdef1), (Ym - (i+1)*Ydef1),0); usleep(16000); break; case 1 : drawPlus(X1, (Y1 + i*Ydef1),1); drawPlus(X1, (Y1 + (i+1)*Ydef1),0); usleep(16000); break; case 2 : drawPlus((X1 + i*Xdef2), Y2,1); drawPlus((X1 + (i+1)*Xdef2), Y2,0); usleep(16000); break; case 3 : drawPlus(X2, (Y2 - i*Ydef2),1); drawPlus(X2, (Y2 - (i+1)*Ydef2),0); usleep(16000); break; case 4 : drawPlus(X2, Y1,1); usleep(20000); break; } } } printf("\n ***** Xavg0 = %d *****",Xavg[0]); printf("\n ***** Xavg1 = %d *****",Xavg[1]); printf("\n ***** Xavg2 = %d *****",Xavg[2]); printf("\n ***** Xavg3 = %d *****",Xavg[3]); printf("\n ***** Xavg4 = %d *****",Xavg[4]); printf("\n\n ***** Yavg0 = %d *****",Yavg[0]); printf("\n ***** Yavg1 = %d *****",Yavg[1]); printf("\n ***** Yavg2 = %d *****",Yavg[2]); printf("\n ***** Yavg3 = %d *****",Yavg[3]); printf("\n ***** Yavg4 = %d *****",Yavg[4]); } void get_XYmax(void) { Xd = (Xavg[2] >= Xavg[1]) ? Xavg[2] - Xavg[1] : Xavg[1] - Xavg[2]; Yd = (Yavg[4] >= Yavg[1]) ? Yavg[4] - Yavg[1] : Yavg[1] - Yavg[4]; if ((Xd <= ERROR_RATE) && (Yd <= ERROR_RATE)) { Xd = (Xavg[3] >= Xavg[4]) ? Xavg[3] - Xavg[4] : Xavg[4] - Xavg[3]; Yd = (Yavg[3] >= Yavg[2]) ? Yavg[3] - Yavg[2] : Yavg[2] - Yavg[3]; if ((Xd <= ERROR_RATE) && (Yd <= ERROR_RATE)) { Xd = (((Xavg[1]+Xavg[4])/2) >= Xavg[0]) ? (Xavg[1]+Xavg[4])/2-Xavg[0] : Xavg[0]-(Xavg[1]+Xavg[4])/2; Yd = (((Yavg[1]+Yavg[2])/2) >= Yavg[0]) ? (Yavg[1]+Yavg[2])/2-Yavg[0] : Yavg[0]-(Yavg[1]+Yavg[2])/2; if ((Xd <= ERROR_RATE) && (Yd <= ERROR_RATE)) { Xd = (((Xavg[2]+Xavg[3])/2) >= Xavg[0]) ? (Xavg[2]+Xavg[3])/2-Xavg[0] : Xavg[0]-(Xavg[2]+Xavg[3])/2; Yd = (((Yavg[4]+Yavg[3])/2) >= Yavg[0]) ? (Yavg[4]+Yavg[3])/2-Yavg[0] : Yavg[0]-(Yavg[4]+Yavg[3])/2; if ((Xd <= ERROR_RATE) && (Yd <= ERROR_RATE)) { Xp1 = (float)(Xavg[1] + Xavg[2])/2; Xp2 = (float)(Xavg[3] + Xavg[4])/2; Yp1 = (float)(Yavg[1] + Yavg[4])/2; Yp2 = (float)(Yavg[2] + Yavg[3])/2; Xpd = (float)(Xp2 - Xp1)/(float)(X2 - X1); Ypd = (float)(Yp2 - Yp1)/(float)(Y2 - Y1); XXmin = Xp1 - Xpd*X1; XXmax = Xp2 + Xpd*X1; YYmin = Yp1 - Ypd*Y1; YYmax = Yp2 + Ypd*Y1; printf("\n ***** Xpd = %f *****",Xpd); printf("\n ***** Ypd = %f *****",Ypd); printf("\n ***** XXmax = %d *****",XXmax); printf("\n ***** XXmin = %d *****",XXmin); printf("\n ***** YYmax = %d *****",YYmax); printf("\n ***** YYmin = %d *****",YYmin); touch_ok = 1; } } } } } void getXY_b(void) { if (dev_read()==ERROR) return; else { Xd = p.x; Yd = p.y; } printf("\n Coordination - : Xd = %d ; Yd = %d\n",Xd,Yd); penup_check(); } void getXY_a(void) { if (dev_read()==ERROR) return; else { Xd = p.x; Yd = p.y; } do { if (dev_buf_clr()==ERROR) return; else { if (cal_t.buf_clr==0) { if (dev_read()==ERROR) return; else { Xd = p.x; Yd = p.y; } } } if (dev_penup()==ERROR) return; }while(!cal_t.penup); printf("\n Coordination - : Xd = %d ; Yd = %d\n",Xd,Yd); penup_check(); } int dev_open(void) { if ((dev_no=open(DEV_NODE,O_SYNC)) < 0) { printf("can't open touchscreen device!\n"); return ERROR; } else { printf(" Open dev_no = %d\n",dev_no); return 1; } } int dev_close(void) { if (close(dev_no) < 0) { printf("can't close touchscreen device!\n\n"); return ERROR; } else { printf(" Close dev\n"); return 1; } } int dev_read(void) { int error_code; if ((error_code=read(dev_no,&p,8)) < 0) { printf("can't read touchscreen!\n"); return ERROR; } else { // printf("E = %d p = %d x = %d y = %d\n",error_code,p.p,p.x,p.y); return 1; } } int dev_dis(void) { int error_code; if ((error_code=ioctl(dev_no,TIODIS_CALI,0)) < 0) { printf("can't set the disable bit of the touchscreen device!\n"); printf(" ERROR_CODE = %d \n",error_code); return ERROR; } else { printf(" set OK!\n"); return 1; } } int dev_getall(void) { int error_code; if ((error_code=ioctl(dev_no,TIOGET_CALI,&cal_t)) < 0) { printf("can't get the parameters of the touchscreen device!\n"); printf(" ERROR_CODE = %d \n",error_code); return ERROR; } else { print_par(); return 1; } } int dev_setall(void) { cal_t.enable = 1; cal_t.x_max = XXmax; /* offset for x pos */ cal_t.y_max = YYmax; cal_t.p_max = 1; cal_t.x_min = XXmin; /* offset for x pos */ cal_t.y_min = YYmin; cal_t.p_min = 1; cal_t.x_pd = Xpd*SCALE; /* offset for x pos */ cal_t.y_pd = Ypd*SCALE; cal_t.p_pd = 1; print_par(); if (ioctl(dev_no,TIOSET_CALI,&cal_t) < 0) { printf("can't set the parameters of the touchscreen device!\n"); return ERROR; } else return 1; } void print_par(void) { printf(" enable = %d\n",cal_t.enable); printf(" x_min = %d\n",cal_t.x_min); printf(" y_min = %d\n",cal_t.y_min); printf(" x_pd = %d\n",cal_t.x_pd); printf(" y_pd = %d\n",cal_t.y_pd); printf(" penup = %d\n",cal_t.penup); printf(" buf_clr = %d\n",cal_t.buf_clr); } int ts_buf_clr(void) { int error_code; if ((error_code=ioctl(dev_no,TIO_BUF_CLR,0)) < 0) { printf("can't clear the parameters of the touchscreen device!\n"); printf(" ERROR_CODE = %d \n",error_code); return ERROR; } else return 1; } int dev_buf_clr(void) { if (ioctl(dev_no,TIOGET_BUFCLR,&cal_t) < 0) { printf("can't get the parameters of the touchscreen device!\n"); return ERROR; } else return 1; } int dev_penup(void) { if (ioctl(dev_no,TIOGET_PENUP,&cal_t) < 0) { printf("can't get the parameters of the touchscreen device!\n"); return ERROR; } else return 1; } static void drawPlus (int xcoord, int ycoord,int delete) { int hx_coord1,hy_coord1,hx_coord2,hy_coord2; int vx_coord1,vy_coord1,vx_coord2,vy_coord2; /* work out the horizontal and vertical line coords */ /* horizontal line */ hx_coord1= xcoord - (SZ_XHAIR/2); hx_coord2= xcoord + (SZ_XHAIR/2); hy_coord1=hy_coord2=ycoord; /* vertical line */ vx_coord1=vx_coord2=xcoord; vy_coord1= ycoord - (SZ_XHAIR/2); vy_coord2= ycoord + (SZ_XHAIR/2); /* check boundaries */ if ( hx_coord1 < 0 || hx_coord1 > SCREEN_WIDTH ) return; if ( hx_coord2 < 0 || hx_coord2 > SCREEN_WIDTH ) return; if ( hy_coord1 < 0 || hy_coord1 > SCREEN_HEIGHT) return; if ( vx_coord1 < 0 || vx_coord1 > SCREEN_WIDTH ) return; if ( vy_coord1 < 0 || vy_coord1 > SCREEN_HEIGHT ) return; if ( vy_coord2 < 0 || vy_coord2 > SCREEN_HEIGHT ) return; if (!delete ) XSetForeground(dpy,gc,whiteColor); else XSetForeground(dpy,gc,blackColor); /* draw horizontal line */ XDrawLine (dpy,w,gc,hx_coord1,hy_coord1,hx_coord2,hy_coord2); /* draw vertical line */ XDrawLine (dpy,w,gc,vx_coord1,vy_coord1,vx_coord2,vy_coord2); XFlush(dpy); } int initX(void) { /* call Xlib directly to init our display */ dpy = XOpenDisplay(NIL); assert(dpy); blackColor = BlackPixel(dpy,DefaultScreen(dpy) ); whiteColor = WhitePixel(dpy,DefaultScreen(dpy) ); w = XCreateSimpleWindow(dpy,DefaultRootWindow(dpy), 0 , 0, SCREEN_WIDTH,SCREEN_HEIGHT, 0, blackColor,blackColor ); XSelectInput(dpy,w,StructureNotifyMask); XMapWindow(dpy,w); gc = XCreateGC(dpy,w,0,NIL); XSetForeground(dpy,gc,whiteColor); for(;;) { XEvent e; /* Read next event */ XNextEvent (dpy, &e); /* this is the blocking version */ if( e.type == MapNotify) break; } // XDrawLine (dpy,w,gc,10,60,180,20); // XDrawLine (dpy,w,gc,160,120,300,220); // XFlush(dpy); // sleep(5); return (dpy) ? 1 : -1; }