📄 calibrate.c
字号:
} /* end of pix_cal_GetDrawPt() *//*******************************************************************************\**** Function: int pix_cal_GetDataPt()** Desc: Gets the raw data (point data) from the device file and stores** it into the CalPt_t structure passed in** Accepts: CalPt_t *ptdata = Ptr to storage of x/y coordinates** Returns: int; 0 on successful read, -1 on error**\*******************************************************************************/intpix_cal_GetDataPt(CalPt_t * ptdata){ int nsample = 0, /* Current number of samples received */ rc = 0, /* Result code */ rdsz; /* read size */ CalPt_t cur_data = { 0, 0 }; /* Current data */ TS_EVENT ts_ev; /* Event structure */ /* ** Determine if the device needs to be opened (this will only happen the first ** time this function is called */ if (!(cal_flags & CAL_FLAGS_DEVOPEN) || devfd == -1) { if ((devfd = cal_OpenDev()) == -1) return (devfd); } /* end of if */ /* Get CAL_MAX_SAMPLE samples to average out */ while (1) { rdsz = 0; while (rdsz < sizeof(TS_EVENT)) { if ((rc = read(devfd, &ts_ev, sizeof(TS_EVENT))) == -1) { if (errno == EINTR) continue; else break; } /* end of if */ rdsz += rc; } /* end of if */ /* Again, check for error condition */ if (rc == -1) break; printf("DATA[%d] %d, %d, %d\n", nsample, ts_ev.x, ts_ev.y, ts_ev.pressure); if (ts_ev.pressure == 0 && nsample > CAL_MAX_SAMPLE) { break; } /* end of if */ else if (ts_ev.x >= 0 && ts_ev.y >= 0) { /* ** The if conditional was added 10/29/01 -- JMW, because holding down the stylus ** would cause erroneous readings due to pressure variance....If this isn't the ** case, please correct me....x */ if (nsample <= CAL_MAX_SAMPLE) { cur_data.x += ts_ev.x; cur_data.y += ts_ev.y; nsample++; } /* end of if */ } /* end of else-if */ } /* end of while */ if (nsample) { cur_data.x /= nsample; cur_data.y /= nsample; memcpy(ptdata, &cur_data, sizeof(CalPt_t)); } /* end of if */ return ((nsample == 0) ? -1 : 0);} /* end of pix_cal_GetDataPtr() *//*******************************************************************************\**** Function: int pix_cal_Calibrate()** Desc: ipaq calibration routine which calculates the calibration values** based on the control and user specific data points** Accepts: int npts = Number of control/data points to process** CalPt_t *ctrldata = Array of npts control points** CalPt_t *userdata = Array of npts user points** Returns: int; 0 on success, -1 on error, PIXLIB_STUB_VAL for a stubbed** function.**\*******************************************************************************/intpix_cal_Calibrate(int npts, CalPt_t * ctrldata, CalPt_t * userdata){ int x, y, dx, dy, flag; int xscale0, xscale1, xtrans0, xtrans1; int yscale0, yscale1, ytrans0, ytrans1; int xyswap, xraw, yraw; TS_CAL new_cal; /* Calibration values to send to kernel */ flag = 0; /* See if the device file needs to be opened */ if (!(cal_flags & CAL_FLAGS_DEVOPEN) || devfd == -1) { if ((devfd = cal_OpenDev()) == -1) { printf("Unable to open device!\n"); return (devfd); } } /* end of if */ /* Calculate ABS(x1-x0) */ dx = ((x = userdata[1].x - userdata[0].x) < 0 ? -x : x); dy = ((y = userdata[1].y - userdata[0].y) < 0 ? -y : y); /* CF (0,0) --------->Y X +-------+---------------+- | | | | V | |xa0,ya0 | +-------O---------------+ -- | | | dx or dy +-------+---------------O -- ^ | | | xa1,ya1 | | | | Y +-------+---------------+ (0,0) -------->X Work out where the origin is, either at the TLH or BLH corners. Initialise xp such that it points to the array containing the X coords Initialise yp such that it points to the array containing the Y coords */ if (dx < dy) { xyswap = 1; } else { xyswap = 0; } xraw = CAL_GETX(xyswap, userdata[4]); yraw = CAL_GETY(xyswap, userdata[4]); /* We have MAX_CAL_POINTS sets of x,y coordinates. If we plot Xcal against Xraw we get two equations, each of a straight line. One for the Xcoord and the other for the Y coord. This line models the linear characteristics of the ts A/D converter. Xcal = m*Xraw + Cx Ycal = m*Yraw + Cy X/Ycal is the calibrated coord which is the pixel pos on the screen. X/Yraw is the uncalibrated X coord. m is the xscale ( gradient of line) Cx/y is the trans (constant) xscale 'm' can be got by calculating the gradient between two data points Example Xscale0 = (Xcal1 - Xcal0 ) / (Xraw1 - Xraw0) trans = Xcal - mXraw What is actualy done is to take the Ave of two measurements Example Xtrans0 = ( (Xcal0 - mXraw0) + (Xcal3 - mXraw3) ) / 2 We repeat the above procedure to calculate Yscale0 and Ytrans0 and repeat the whole lot again using two new data indexes 1 and 2 giving 4 new variables Xscale1, Xtrans1, Yscale1,Ytrans1, making a total of eight. The final calibration variables are the average of data ponts 0,3 and 1,2 xscale = (Xscale0 + Xscale1) / 2 yscale = (Yscale0 + Yscale1) / 2 xtrans = (Xtrans0 + Xtrans1) /2 ytrans = (Ytrans0 + Ytrans1) /2 */ xscale0 = ((ctrldata[0].x - ctrldata[3].x) << 8) / (CAL_GETX(xyswap, userdata[0]) - CAL_GETX(xyswap, userdata[3])); xtrans0 = ((ctrldata[0].x - ((CAL_GETX(xyswap, userdata[0]) * xscale0) >> 8)) + (ctrldata[3].x - ((CAL_GETX(xyswap, userdata[3]) * xscale0) >> 8))) / 2; yscale0 = ((ctrldata[0].y - ctrldata[3].y) << 8) / (CAL_GETY(xyswap, userdata[0]) - CAL_GETY(xyswap, userdata[3])); ytrans0 = ((ctrldata[0].y - ((CAL_GETY(xyswap, userdata[0]) * yscale0) >> 8)) + (ctrldata[3].y - ((CAL_GETY(xyswap, userdata[3]) * yscale0) >> 8))) / 2; xscale1 = ((ctrldata[1].x - ctrldata[2].x) << 8) / (CAL_GETX(xyswap, userdata[1]) - CAL_GETX(xyswap, userdata[2])); xtrans1 = ((ctrldata[1].x - ((CAL_GETX(xyswap, userdata[1]) * xscale1) >> 8)) + (ctrldata[2].x - ((CAL_GETX(xyswap, userdata[2]) * xscale1) >> 8))) / 2; yscale1 = ((ctrldata[1].y - ctrldata[2].y) << 8) / (CAL_GETY(xyswap, userdata[1]) - CAL_GETY(xyswap, userdata[2])); ytrans1 = ((ctrldata[1].y - ((CAL_GETY(xyswap, userdata[1]) * yscale1) >> 8)) + (ctrldata[2].y - ((CAL_GETY(xyswap, userdata[2]) * yscale1) >> 8))) / 2; new_cal.xscale = (xscale0 + xscale1) / 2; new_cal.xtrans = (xtrans0 + xtrans1) / 2; new_cal.yscale = (yscale0 + yscale1) / 2; new_cal.ytrans = (ytrans0 + ytrans1) / 2; new_cal.xyswap = xyswap;#ifdef FOO new_cal.yscale = (xscale0 + xscale1) / 2; new_cal.ytrans = (xtrans0 + xtrans1) / 2; new_cal.xscale = (yscale0 + yscale1) / 2; new_cal.xtrans = (ytrans0 + ytrans1) / 2; new_cal.xyswap = xyswap;#endif /* Now check it with center coords */ printf("CHECK with Center Coords (160,120): xraw=%d yraw=%d\n",xraw,yraw); x = ((new_cal.xscale * xraw) >> 8) + new_cal.xtrans; y = ((new_cal.yscale * yraw) >> 8) + new_cal.ytrans; printf("CHECK: x(center)=%d y(center)=%d\n",x,y); /* store this calibration in the device */ if (ioctl(devfd, TS_SET_CAL, (void *) &new_cal) != 0) { perror("TS_SET_CALIBRATION ioctl fail\n"); return -1; } printf("SET %d, %d, %d, %d, %d\n", new_cal.xscale, new_cal.yscale, new_cal.xtrans, new_cal.ytrans, new_cal.xyswap); printf("Set the calibration\n"); return 0;} /* end of pix_cal_Calibrate() */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -