Forked para SNOCC

Dependencies:   GPS

Dependents:   SNOCC_V1 SNOCC_V2

Fork of RA8875 by SNOCC

Revision:
83:7bad0068cca0
Parent:
81:01da2e34283d
Child:
85:022bba13c5c4
--- a/RA8875_Touch.cpp	Tue Dec 30 23:45:37 2014 +0000
+++ b/RA8875_Touch.cpp	Thu Jan 01 20:35:37 2015 +0000
@@ -3,6 +3,9 @@
 
 #include "RA8875.h"
 
+#define NOTOUCH_TIMEOUT_uS 100000
+#define TOUCH_TICKER_uS      1000
+
 // ### Touch Panel support code additions begin here
 
 RetCode_t RA8875::TouchPanelInit(void)
@@ -13,6 +16,11 @@
     WriteCommand(TPCR1, TP_MODE_DEFAULT | TP_DEBOUNCE_DEFAULT);
     WriteCommand(INTC1, ReadCommand(INTC1) | RA8875_INT_TP);        // reg INTC1: Enable Touch Panel Interrupts (D2 = 1)
     WriteCommand(INTC2, RA8875_INT_TP);                            // reg INTC2: Clear any TP interrupt flag
+    touchSample = 0;
+    touchState = no_cal;
+    touchTicker.attach_us(this, &RA8875::_TouchTicker, TOUCH_TICKER_uS);
+    touchTimer.start();
+    touchTimer.reset();
     return noerror;
 }
 
@@ -34,6 +42,16 @@
     // Set up the interrupt flag and enable bits
     WriteCommand(INTC1, ReadCommand(INTC1) | RA8875_INT_TP);        // reg INTC1: Enable Touch Panel Interrupts (D2 = 1)
     WriteCommand(INTC2, RA8875_INT_TP);                            // reg INTC2: Clear any TP interrupt flag
+    touchSample = 0;
+    touchState = no_cal;
+    if (bTpEnable == TP_ENABLE) {
+        touchTicker.attach_us(this, &RA8875::_TouchTicker, TOUCH_TICKER_uS);
+        touchTimer.start();
+        touchTimer.reset();
+    } else {
+        touchTicker.detach();
+        touchTimer.stop();
+    }
     return noerror;
 }
 
@@ -60,8 +78,10 @@
 {
     point_t pTest[3];
     point_t pSample[3];
-    loc_t x,y;
+    int x,y;
     
+    while (TouchPanelA2DFiltered(&x, &y))
+        wait_ms(20);
     cls();
     if (msg)
         puts(msg);
@@ -145,32 +165,32 @@
  *  operations to scale results by a factor of 2 or even 4.  
  *
  */
-bool RA8875::TouchPanelReadable(point_t * TouchPoint)
+TouchCode_t RA8875::TouchPanelReadable(point_t * TouchPoint)
 {
-    bool touched = false;
-    point_t screenpoint = {0, 0};
+    int a2dX = 0;
+    int a2dY = 0;
     
-    if (TouchPanelA2DFiltered(&screenpoint.x, &screenpoint.y)) {
-        touched = true;
+    TouchCode_t ts = TouchPanelA2DFiltered(&a2dX, &a2dY);
+    if (ts != no_touch) {
         if (tpMatrix.Divider != 0 && TouchPoint) {
             /* Operation order is important since we are doing integer */
             /*  math. Make sure you add all terms together before      */
             /*  dividing, so that the remainder is not rounded off     */
             /*  prematurely.                                           */
-            TouchPoint->x = ( (tpMatrix.An * screenpoint.x) +
-                              (tpMatrix.Bn * screenpoint.y) +
+            TouchPoint->x = ( (tpMatrix.An * a2dX) +
+                              (tpMatrix.Bn * a2dY) +
                               tpMatrix.Cn
                             ) / tpMatrix.Divider ;
 
-            TouchPoint->y = ( (tpMatrix.Dn * screenpoint.x) +
-                              (tpMatrix.En * screenpoint.y) +
+            TouchPoint->y = ( (tpMatrix.Dn * a2dX) +
+                              (tpMatrix.En * a2dY) +
                               tpMatrix.Fn
                             ) / tpMatrix.Divider ;
         } else {
-            touched = false;
+            ts = no_cal;
         }
     }
-    return touched;
+    return ts;
 }
 
 
@@ -179,27 +199,76 @@
     if (matrixPtr == NULL || matrixPtr->Divider == 0)
         return bad_parameter;
     memcpy(&tpMatrix, matrixPtr, sizeof(tpMatrix_t));
+    touchState = no_touch;
     return noerror;
 }
 
 
-bool RA8875::TouchPanelA2DFiltered(loc_t *x, loc_t *y)
+static void InsertionSort(int * buf, int bufsize)
+{
+    int i, j;
+    int temp;
+    
+    for(i = 1; i <= bufsize; i++) {
+        temp = buf[i];
+        j = i;
+        while( j && (buf[j-1] > temp) ) {
+            buf[j] = buf[j-1];
+            j = j-1;
+        }
+        buf[j] = temp;
+    } // End of sort
+}
+
+
+void RA8875::_TouchTicker(void)
 {
-    unsigned char touchready;
-    static int xbuf[TPBUFSIZE], ybuf[TPBUFSIZE], sample = 0;
-    int i, j, temp;
+    if (touchTimer.read_us() > NOTOUCH_TIMEOUT_uS) {
+        touchSample = 0;
+        if (touchState == held)
+            touchState = release;
+        else
+            touchState = no_touch;
+        touchTimer.reset();
+    }
+}
+
+TouchCode_t RA8875::TouchPanelA2DRaw(int *x, int *y)
+{
+    if( (ReadCommand(INTC2) & RA8875_INT_TP) ) {        // Test for TP Interrupt pending in register INTC2
+        touchTimer.reset();
+        *y = ReadCommand(TPYH) << 2 | ( (ReadCommand(TPXYL) & 0xC) >> 2 );   // D[9:2] from reg TPYH, D[1:0] from reg TPXYL[3:2]
+        *x = ReadCommand(TPXH) << 2 | ( (ReadCommand(TPXYL) & 0x3)      );   // D[9:2] from reg TPXH, D[1:0] from reg TPXYL[1:0]
+        WriteCommand(INTC2, RA8875_INT_TP);            // reg INTC2: Clear that TP interrupt flag
+        touchState = touch;
+    } else {
+        touchState = no_touch;
+    }
+    return touchState;
+}
+
+TouchCode_t RA8875::TouchPanelA2DFiltered(int *x, int *y)
+{
+    static int xbuf[TPBUFSIZE], ybuf[TPBUFSIZE];
+    static int lastX, lastY;
+    int i, j;
+    TouchCode_t ret = touchState;
 
     if( (ReadCommand(INTC2) & RA8875_INT_TP) ) {        // Test for TP Interrupt pending in register INTC2
+        touchTimer.reset();
         // Get the next data samples
-        ybuf[sample] =  ReadCommand(TPYH) << 2 | ( (ReadCommand(TPXYL) & 0xC) >> 2 );   // D[9:2] from reg TPYH, D[1:0] from reg TPXYL[3:2]
-        xbuf[sample] =  ReadCommand(TPXH) << 2 | ( (ReadCommand(TPXYL) & 0x3)      );   // D[9:2] from reg TPXH, D[1:0] from reg TPXYL[1:0]
+        ybuf[touchSample] =  ReadCommand(TPYH) << 2 | ( (ReadCommand(TPXYL) & 0xC) >> 2 );   // D[9:2] from reg TPYH, D[1:0] from reg TPXYL[3:2]
+        xbuf[touchSample] =  ReadCommand(TPXH) << 2 | ( (ReadCommand(TPXYL) & 0x3)      );   // D[9:2] from reg TPXH, D[1:0] from reg TPXYL[1:0]
         // Check for a complete set
-        if(++sample == TPBUFSIZE) {
+        if(++touchSample == TPBUFSIZE) {
             // Buffers are full, so process them using Finn's method described in Analog Dialogue No. 44, Feb 2010
             // This requires sorting the samples in order of size, then discarding the top 25% and
             //   bottom 25% as noise spikes. Finally, the middle 50% of the values are averaged to
             //   reduce Gaussian noise.
-
+#if 1
+            InsertionSort(ybuf, TPBUFSIZE);
+            InsertionSort(xbuf, TPBUFSIZE);
+#else
             // Sort the Y buffer using an Insertion Sort
             for(i = 1; i <= TPBUFSIZE; i++) {
                 temp = ybuf[i];
@@ -220,44 +289,49 @@
                 }
                 xbuf[j] = temp;
             } // End of X sort
+#endif
             // Average the middle half of the  Y values and report them
             j = 0;
             for(i = (TPBUFSIZE/4) - 1; i < TPBUFSIZE - TPBUFSIZE/4; i++ ) {
                 j += ybuf[i];
             }
-            *y = j * (float)2/TPBUFSIZE;    // This is the average
+            *y = lastY = j * (float)2/TPBUFSIZE;    // This is the average
             // Average the middle half of the  X values and report them
             j = 0;
             for(i = (TPBUFSIZE/4) - 1; i < TPBUFSIZE - TPBUFSIZE/4; i++ ) {
                 j += xbuf[i];
             }
-            *x = j * (float)2/TPBUFSIZE;    // This is the average
+            *x = lastX = j * (float)2/TPBUFSIZE;    // This is the average
             // Tidy up and return
-            touchready = 1;
-            sample = 0;             // Ready to start on the next set of data samples
+            if (touchState == touch || touchState == held)
+                touchState = held;
+            else
+                touchState = touch;
+            ret = touchState;
+            touchSample = 0;             // Ready to start on the next set of data samples
         } else {
             // Buffer not yet full, so do not return any results yet
-            touchready = 0;
+            if (touchState == touch || touchState == held) {
+                *x = lastX;
+                *y = lastY;
+                ret = touchState = held;
+            }
         }
         WriteCommand(INTC2, RA8875_INT_TP);            // reg INTC2: Clear that TP interrupt flag
     } // End of initial if -- data has been read and processed
-    else
-        touchready = 0;         // Touch Panel "Int" was not set
-    return touchready;
-}
-
-bool RA8875::TouchPanelA2DRaw(loc_t *x, loc_t *y)
-{
-    unsigned char touchready;
-
-    if( (ReadCommand(INTC2) & RA8875_INT_TP) ) {        // Test for TP Interrupt pending in register INTC2
-        *y =  ReadCommand(TPYH) << 2 | ( (ReadCommand(TPXYL) & 0xC) >> 2 );   // D[9:2] from reg TPYH, D[1:0] from reg TPXYL[3:2]
-        *x =  ReadCommand(TPXH) << 2 | ( (ReadCommand(TPXYL) & 0x3)      );   // D[9:2] from reg TPXH, D[1:0] from reg TPXYL[1:0]
-        WriteCommand(INTC2, RA8875_INT_TP);            // reg INTC2: Clear that TP interrupt flag
-        touchready = 1;
-    } else
-        touchready = 0;
-    return touchready;
+    else {
+        if (touchState == touch || touchState == held) {
+            *x = lastX;
+            *y = lastY;
+            ret = touchState = held;
+        } else if (touchState == release) {
+            *x = lastX;
+            *y = lastY;
+            ret = release;
+            touchState = no_touch;
+        }
+    }
+    return ret;
 }
 
 /*   The following section is derived from Carlos E. Vidales.
@@ -451,6 +525,7 @@
         tpMatrix.Fn = (screenPtr[2].x * displayPtr[1].y - screenPtr[1].x * displayPtr[2].y) * screenPtr[0].y +
                       (screenPtr[0].x * displayPtr[2].y - screenPtr[2].x * displayPtr[0].y) * screenPtr[1].y +
                       (screenPtr[1].x * displayPtr[0].y - screenPtr[0].x * displayPtr[1].y) * screenPtr[2].y ;
+        touchState = no_touch;
         if (matrixPtr)
             memcpy(matrixPtr, &tpMatrix, sizeof(tpMatrix_t));
     }