summaryrefslogtreecommitdiff
path: root/NxWidgets/nxwm
diff options
context:
space:
mode:
authorGregory Nutt <gnutt@nuttx.org>2013-10-17 12:07:14 -0600
committerGregory Nutt <gnutt@nuttx.org>2013-10-17 12:07:14 -0600
commit3585cc73d6f645bbf052e7411d52097f5b5b338a (patch)
tree350a020700b3e56bc18b86c3f2ef319a5da5a995 /NxWidgets/nxwm
parentcfbd603eeb19635d391dfafb74deb06611c9486a (diff)
downloadnuttx-3585cc73d6f645bbf052e7411d52097f5b5b338a.tar.gz
nuttx-3585cc73d6f645bbf052e7411d52097f5b5b338a.tar.bz2
nuttx-3585cc73d6f645bbf052e7411d52097f5b5b338a.zip
New touchscreen scaling algorithm for the case where measured X values vary with y position (and vice versa)
Diffstat (limited to 'NxWidgets/nxwm')
-rw-r--r--NxWidgets/nxwm/include/ccalibration.hxx26
-rw-r--r--NxWidgets/nxwm/src/ccalibration.cxx68
-rw-r--r--NxWidgets/nxwm/src/ctouchscreen.cxx64
3 files changed, 155 insertions, 3 deletions
diff --git a/NxWidgets/nxwm/include/ccalibration.hxx b/NxWidgets/nxwm/include/ccalibration.hxx
index 30a48f7eb..d9cf3a7de 100644
--- a/NxWidgets/nxwm/include/ccalibration.hxx
+++ b/NxWidgets/nxwm/include/ccalibration.hxx
@@ -85,14 +85,36 @@ namespace NxWM
* Touchscreen calibration data
*/
+#ifdef CONFIG_NXWM_CALIBRATION_ANISOTROPIC
+ struct SCalibrationLine
+ {
+ float slope; /**< The slope of a line */
+ float offset; /**< The offset of a line */
+ };
+
struct SCalibrationData
{
- b16_t xSlope; // X conversion: xSlope*(x) + xOffset
+ struct SCalibrationLine left; /**< Describes Y values along left edge */
+ struct SCalibrationLine right; /**< Describes Y values along right edge */
+ struct SCalibrationLine top; /**< Describes X values along top */
+ struct SCalibrationLine bottom; /**< Describes X values along bottom edge */
+ nxgl_coord_t leftX; /**< Left X value used in calibration */
+ nxgl_coord_t rightX; /**< Right X value used in calibration */
+ nxgl_coord_t topY; /**< Top Y value used in calibration */
+ nxgl_coord_t bottomY; /**< Bottom Y value used in calibration */
+ };
+
+#else
+ struct SCalibrationData
+ {
+ b16_t xSlope; /**< X conversion: xSlope*(x) + xOffset */
b16_t xOffset;
- b16_t ySlope; // Y conversion: ySlope*(y) + yOffset
+ b16_t ySlope; /**< Y conversion: ySlope*(y) + yOffset */
b16_t yOffset;
};
+#endif
+
/**
* The CCalibration class provides the the calibration window and obtains
* callibration data.
diff --git a/NxWidgets/nxwm/src/ccalibration.cxx b/NxWidgets/nxwm/src/ccalibration.cxx
index 416f15883..01bdf3b44 100644
--- a/NxWidgets/nxwm/src/ccalibration.cxx
+++ b/NxWidgets/nxwm/src/ccalibration.cxx
@@ -1128,6 +1128,72 @@ bool CCalibration::createCalibrationData(struct SCalibrationData &data)
return false;
}
+#ifdef CONFIG_NXWM_CALIBRATION_ANISOTROPIC
+ // X lines:
+ //
+ // x2 = slope*y1 + offset
+ //
+ // slope = (bottomY - topY) / (bottomX - topX)
+ // offset = (topY - topX * slope)
+
+ float topX = (float)m_calibData[CALIB_UPPER_LEFT_INDEX].x;
+ float bottomX = (float)m_calibData[CALIB_LOWER_LEFT_INDEX].x;
+
+ float topY = (float)m_calibData[CALIB_UPPER_LEFT_INDEX].y;
+ float bottomY = (float)m_calibData[CALIB_LOWER_LEFT_INDEX].y;
+
+ data.left.slope = (bottomX - topX) / (bottomY - topY);
+ data.left.offset = topX - topY * data.left.slope;
+
+ gdbg("Left slope: %f offset: %f\n", data.left.slope, data.left.offset);
+
+ topX = (float)m_calibData[CALIB_UPPER_RIGHT_INDEX].x;
+ bottomX = (float)m_calibData[CALIB_LOWER_RIGHT_INDEX].x;
+
+ topY = (float)m_calibData[CALIB_UPPER_RIGHT_INDEX].y;
+ bottomY = (float)m_calibData[CALIB_LOWER_RIGHT_INDEX].y;
+
+ data.right.slope = (bottomX - topX) / (bottomY - topY);
+ data.right.offset = topX - topY * data.right.slope;
+
+ gdbg("Right slope: %f offset: %f\n", data.right.slope, data.right.offset);
+
+ // Y lines:
+ //
+ // y2 = slope*x1 + offset
+ //
+ // slope = (rightX - topX) / (rightY - leftY)
+ // offset = (topX - leftY * slope)
+
+ float leftX = (float)m_calibData[CALIB_UPPER_LEFT_INDEX].x;
+ float rightX = (float)m_calibData[CALIB_UPPER_RIGHT_INDEX].x;
+
+ float leftY = (float)m_calibData[CALIB_UPPER_LEFT_INDEX].y;
+ float rightY = (float)m_calibData[CALIB_UPPER_RIGHT_INDEX].y;
+
+ data.top.slope = (rightY - leftY) / (rightX - leftX);
+ data.top.offset = leftY - leftX * data.top.slope;
+
+ gdbg("Top slope: %f offset: %f\n", data.top.slope, data.top.offset);
+
+ leftX = (float)m_calibData[CALIB_LOWER_LEFT_INDEX].x;
+ rightX = (float)m_calibData[CALIB_LOWER_RIGHT_INDEX].x;
+
+ leftY = (float)m_calibData[CALIB_LOWER_LEFT_INDEX].y;
+ rightY = (float)m_calibData[CALIB_LOWER_RIGHT_INDEX].y;
+
+ data.bottom.slope = (rightY - leftY) / (rightX - leftX);
+ data.bottom.offset = leftY - leftX * data.bottom.slope;
+
+ gdbg("Bottom slope: %f offset: %f\n", data.bottom.slope, data.bottom.offset);
+
+ // Save also the calibration screen positions
+
+ data.leftX = CALIBRATION_LEFTX;
+ data.rightX = CALIBRATION_RIGHTX;
+ data.topY = CALIBRATION_TOPY;
+ data.bottomY = CALIBRATION_BOTTOMY;
+#else
// Calculate the calibration parameters
//
// (scaledX - LEFTX) / (rawX - leftX) = (RIGHTX - LEFTX) / (rightX - leftX)
@@ -1169,6 +1235,8 @@ bool CCalibration::createCalibrationData(struct SCalibrationData &data)
data.yOffset = itob16(CALIBRATION_TOPY) - b16mulb16(topY, data.ySlope);
gdbg("New ySlope: %08x yOffset: %08x\n", data.ySlope, data.yOffset);
+#endif
+
return true;
}
diff --git a/NxWidgets/nxwm/src/ctouchscreen.cxx b/NxWidgets/nxwm/src/ctouchscreen.cxx
index ba25dd95f..1b9c53e4d 100644
--- a/NxWidgets/nxwm/src/ctouchscreen.cxx
+++ b/NxWidgets/nxwm/src/ctouchscreen.cxx
@@ -472,6 +472,66 @@ void CTouchscreen::handleMouseInput(struct touch_sample_s *sample)
}
else
{
+#ifdef CONFIG_NXWM_CALIBRATION_ANISOTROPIC
+ // We have valid coordinates. Get the raw touch
+ // position from the sample
+
+ float rawX = (float)sample->point[0].x;
+ float rawY = (float)sample->point[0].y;
+
+ // Create a line (varying in X) that have the same matching Y values
+ // X lines:
+ //
+ // x2 = slope*y1 + offset
+ //
+ // X value calculated on the left side for the given value of y
+
+ float leftX = rawY * m_calibData.left.slope + m_calibData.left.offset;
+
+ // X value calculated on the right side for the given value of y
+
+ float rightX = rawY * m_calibData.right.slope + m_calibData.right.offset;
+
+ // Line of X values between (m_calibData.leftX,leftX) and (m_calibData.rightX,rightX) the
+ // are possible solutions:
+ //
+ // x2 = slope * x1 - offset
+
+ struct SCalibrationLine xLine;
+ xLine.slope = (float)((int)m_calibData.rightX - (int)m_calibData.leftX) / (rightX - leftX);
+ xLine.offset = (float)m_calibData.leftX - leftX * xLine.slope;
+
+ // Create a line (varying in Y) that have the same matching X value
+ // X lines:
+ //
+ // y2 = slope*x1 + offset
+ //
+ // Y value calculated on the top side for a given value of X
+
+ float topY = rawX * m_calibData.top.slope + m_calibData.top.offset;
+
+ // Y value calculated on the bottom side for a give value of X
+
+ float bottomY = rawX * m_calibData.bottom.slope + m_calibData.bottom.offset;
+
+ // Line of Y values between (topy,m_calibData.topY) and (bottomy,m_calibData.bottomY) that
+ // are possible solutions:
+ //
+ // y2 = slope * y1 - offset
+
+ struct SCalibrationLine yLine;
+ yLine.slope = (float)((int)m_calibData.bottomY - (int)m_calibData.topY) / (bottomY - topY);
+ yLine.offset = (float)m_calibData.topY - topY * yLine.slope;
+
+ // Then scale the raw x and y positions
+
+ float scaledX = rawX * xLine.slope + xLine.offset;
+ float scaledY = rawY * yLine.slope + yLine.offset;
+
+ x = (nxgl_coord_t)scaledX;
+ y = (nxgl_coord_t)scaledY;
+
+#else
// We have valid coordinates. Get the raw touch
// position from the sample
@@ -517,7 +577,9 @@ void CTouchscreen::handleMouseInput(struct touch_sample_s *sample)
y = (nxgl_coord_t)bigY;
}
- vdbg("raw: (%d, %d) scaled: (%d, %d)\n", rawX, rawY, x, y);
+#endif
+
+ gvdbg("raw: (%d, %d) scaled: (%d, %d)\n", rawX, rawY, x, y);
}
// Get the server handle and "inject the mouse data