A library with drivers for different peripherals on the LPC4088 QuickStart Board or related add-on boards.

Dependencies:   FATFileSystem

Dependents:   LPC4088test LPC4088test_ledonly LPC4088test_deleteall LPC4088_RAMtest ... more

Revision:
4:b32cf4ef45c5
Parent:
0:0fdadbc3d852
Child:
6:405c6e5a4eaf
--- a/TSC2046.cpp	Wed Oct 09 07:51:52 2013 +0000
+++ b/TSC2046.cpp	Fri Oct 18 12:48:58 2013 +0200
@@ -1,5 +1,6 @@
 
 #include "mbed.h"
+#include "mbed_debug.h"
 #include "TSC2046.h"
 
 #ifndef ABS
@@ -47,6 +48,7 @@
 #define DEBOUNCE_MAX 10
 #define DEBOUNCE_TOL  3
 
+
 TSC2046::TSC2046(PinName mosi, PinName miso, PinName sck, PinName cs) :
 _spi(mosi, miso, sck), _cs(cs)
 {
@@ -56,19 +58,39 @@
     _spi.frequency(1500000);
     _calibrated = false;
     _initialized = false;
+
+    _calibPoint = TSC2046_NUM_CALIB_POINTS+1;
+
+    _insetPx = 15;
+}
+
+bool TSC2046::init(uint16_t width, uint16_t height) {
+    _width = width;
+    _height = height;
+
+    _cs = 0;
+
+    _spi.write(REF_ON);
+    _spi.write((READ_12BIT_SER(ADS_A2A1A0_vaux) | ADS_PD10_ALL_ON));
+    _spi.write(PWRDOWN);
+
+    _cs = 1;
+
+
+    _initialized = true;
+
+    return true;
 }
 
 
-void TSC2046::read(touchCoordinate_t &coord) {
+bool TSC2046::read(touchCoordinate_t &coord) {
 
     touchCoordinate_t tmpCoord;
     calibPoint_t displayPoint;
     calibPoint_t screenSample;
 
-    if (!_initialized) {
-        init();
-        _initialized = true;
-    }
+    if (!_initialized) return false;
+
 
     readAndFilter(tmpCoord);
 
@@ -92,54 +114,122 @@
         coord.y = tmpCoord.y;
     }
 
-}
-
-void TSC2046::calibrate(touchCoordinate_t &ref1,
-        touchCoordinate_t &ref2,
-        touchCoordinate_t &ref3,
-        touchCoordinate_t &scr1,
-        touchCoordinate_t &scr2,
-        touchCoordinate_t &scr3) {
-
-    calibPoint_t disp[3];
-    calibPoint_t scr[3];
-
-    disp[0].x = ref1.x;
-    disp[0].y = ref1.y;
-    disp[1].x = ref2.x;
-    disp[1].y = ref2.y;
-    disp[2].x = ref3.x;
-    disp[2].y = ref3.y;
-
-    scr[0].x = scr1.x;
-    scr[0].y = scr1.y;
-    scr[1].x = scr2.x;
-    scr[1].y = scr2.y;
-    scr[2].x = scr3.x;
-    scr[2].y = scr3.y;
-
-    setCalibrationMatrix(disp, scr, &_calibMatrix);
-
-    _calibrated = true;
+    return true;
 
 }
 
-void TSC2046::uncalibrate() {
-    _calibrated = false;
+bool TSC2046::calibrateStart() {
+    if (!_initialized) return false;
+
+    _calibPoint = 0;
+
+    return true;
+}
+
+bool TSC2046::getNextCalibratePoint(uint16_t* x, uint16_t* y) {
+    touchCoordinate_t coord;
+
+    if (!_initialized) return false;
+
+    if (x == NULL || y == NULL) return false;
+
+    if (_calibPoint >= TSC2046_NUM_CALIB_POINTS) return false;
+
+    getCalibratePoint(_calibPoint, &coord.x, &coord.y);
+
+    *x = (uint16_t)coord.x;
+    *y = (uint16_t)coord.y;
+    _calibrateValues[_calibPoint][0] = coord;
+
+    return true;
+}
+
+bool TSC2046::waitForCalibratePoint(bool* morePoints, uint32_t timeout) {
+    int result = 0;
+    bool ret = false;
+    int32_t x = 0;
+    int32_t y = 0;
+    touchCoordinate_t coord;
+
+    if (!_initialized) return false;
+
+    do {
+        if (morePoints == NULL || _calibPoint >= TSC2046_NUM_CALIB_POINTS) {
+            break;
+        }
+
+        result = waitForTouch(&x, &y, timeout);
+        if (result != 0) {
+            debug("wait for touch response failed (%d)\n", result);
+            break;
+        }
+
+        coord.x = x;
+        coord.y = y;
+        _calibrateValues[_calibPoint][1] = coord;
+
+        _calibPoint++;
+        *morePoints = (_calibPoint < TSC2046_NUM_CALIB_POINTS);
+
+        if (!(*morePoints)) {
+
+            calibrate(
+                    _calibrateValues[0][0],
+                    _calibrateValues[1][0],
+                    _calibrateValues[2][0],
+                    _calibrateValues[0][1],
+                    _calibrateValues[1][1],
+                    _calibrateValues[2][1]);
+        }
+
+
+        ret = true;
+
+    } while (0);
+
+
+
+    if (!ret) {
+        // calibration must restart if an error occurred
+        _calibPoint = TSC2046_NUM_CALIB_POINTS+1;
+    }
+
+
+
+    return ret;
+
 }
 
 
-void TSC2046::init() {
+bool TSC2046::calibrate(touchCoordinate_t* values, int numValues) {
+    if (values == NULL || numValues < TSC2046_NUM_CALIB_POINTS) return false;
+
+    touchCoordinate_t ref[TSC2046_NUM_CALIB_POINTS];
+    touchCoordinate_t scr[TSC2046_NUM_CALIB_POINTS];
 
-    _cs = 0;
+    for (int i = 0; i < TSC2046_NUM_CALIB_POINTS; i++) {
+        getCalibratePoint(i, &(ref[i].x), &(ref[i].y));
+        scr[i] = values[i];
+    }
+
+    calibrate(ref[0], ref[1], ref[2], scr[0], scr[1], scr[2]);
 
-    _spi.write(REF_ON);
-    _spi.write((READ_12BIT_SER(ADS_A2A1A0_vaux) | ADS_PD10_ALL_ON));
-    _spi.write(PWRDOWN);
+    return true;
+}
+
+
+bool TSC2046::getCalibrationValues(touchCoordinate_t* values, int numValues) {
+    if (values == NULL || numValues < TSC2046_NUM_CALIB_POINTS) return false;
+    if (!_calibrated) return false;
 
-    _cs = 1;
+    for (int i = 0; i < TSC2046_NUM_CALIB_POINTS; i++) {
+        values[i] = _calibrateValues[i][1];
+    }
+
+    return true;
 }
 
+
 void TSC2046::readAndFilter(touchCoordinate_t &coord)
 {
     int32_t ix, iy, iz1, iz2 = 0;
@@ -296,6 +386,90 @@
     return ((data[0] << 8) | data[1]);
 }
 
+void TSC2046::calibrate(touchCoordinate_t &ref1,
+        touchCoordinate_t &ref2,
+        touchCoordinate_t &ref3,
+        touchCoordinate_t &scr1,
+        touchCoordinate_t &scr2,
+        touchCoordinate_t &scr3) {
+
+    calibPoint_t disp[3];
+    calibPoint_t scr[3];
+
+    disp[0].x = ref1.x;
+    disp[0].y = ref1.y;
+    disp[1].x = ref2.x;
+    disp[1].y = ref2.y;
+    disp[2].x = ref3.x;
+    disp[2].y = ref3.y;
+
+    scr[0].x = scr1.x;
+    scr[0].y = scr1.y;
+    scr[1].x = scr2.x;
+    scr[1].y = scr2.y;
+    scr[2].x = scr3.x;
+    scr[2].y = scr3.y;
+
+    setCalibrationMatrix(disp, scr, &_calibMatrix);
+
+    _calibrated = true;
+
+}
+
+void TSC2046::getCalibratePoint(int pointNum, int32_t* x, int32_t *y) {
+    switch(pointNum) {
+    case 0:
+        *x = _insetPx;
+        *y = _height - _insetPx;
+        break;
+    case 1:
+        *x = _width/2;
+        *y = _insetPx;
+        break;
+    case 2:
+        *x = _width - _insetPx;
+        *y = _height - _insetPx;
+        break;
+    }
+}
+
+int TSC2046::waitForTouch(int32_t* x, int32_t* y, uint32_t timeout) {
+    Timer t;
+    touchCoordinate_t coord;
+    bool waitForRelease = false;
+    int32_t tx = 0;
+    int32_t ty = 0;
+
+
+    t.start();
+    while (timeout == 0 || ((uint32_t)t.read_ms() < timeout)) {
+
+        read(coord);
+
+        if (coord.z == 0 && waitForRelease) {
+            *x = tx;
+            *y = ty;
+            break;
+        }
+
+        if (coord.z > 0) {
+            tx = coord.x;
+            ty = coord.y;
+            waitForRelease = true;
+        }
+
+        wait_ms(10);
+    }
+
+    if (timeout > 0 && (uint32_t)t.read_ms() > timeout) {
+        return -1;
+    }
+
+    return 0;
+
+}
+
+
 
 // ############################################################################
 // >>>>>>>> Calibrate code >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
@@ -609,6 +783,7 @@
 }
 
 
+
 // ############################################################################
 // <<<<<<<< Calibrate code <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
 // ############################################################################