Library to control a Graphics TFT connected to 4-wire SPI - revised for the Raio RA8875 Display Controller.

Dependents:   FRDM_RA8875_mPaint RA8875_Demo RA8875_KeyPadDemo SignalGenerator ... more

Fork of SPI_TFT by Peter Drescher

See Components - RA8875 Based Display

Enhanced touch-screen support - where it previous supported both the Resistive Touch and Capacitive Touch based on the FT5206 Touch Controller, now it also has support for the GSL1680 Touch Controller.

Offline Help Manual (Windows chm)

/media/uploads/WiredHome/ra8875.zip.bin (download, rename to .zip and unzip)

Revision:
193:74f80834d59d
Parent:
190:3132b7dfad82
Child:
196:56820026701b
--- a/RA8875_Touch.cpp	Fri Oct 18 20:32:23 2019 +0000
+++ b/RA8875_Touch.cpp	Mon Nov 25 19:55:17 2019 +0000
@@ -61,20 +61,20 @@
     } else {
         INFO("TouchPanelInit: TP_RES");
         //TPCR0: Set enable bit, default sample time, wakeup, and ADC clock
-        WriteCommand(TPCR0, TP_ENABLE | TP_ADC_SAMPLE_DEFAULT_CLKS | TP_ADC_CLKDIV_DEFAULT);
+        WriteCommand(RA8875_TPCR0, TP_ENABLE | TP_ADC_SAMPLE_DEFAULT_CLKS | TP_ADC_CLKDIV_DEFAULT);
         // TPCR1: Set auto/manual, Ref voltage, debounce, manual mode params
-        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
+        WriteCommand(RA8875_TPCR1, TP_MODE_DEFAULT | TP_DEBOUNCE_DEFAULT);
+        WriteCommand(RA8875_INTC1, ReadCommand(RA8875_INTC1) | RA8875_INT_TP);        // reg RA8875_INTC1: Enable Touch Panel Interrupts (D2 = 1)
+        WriteCommand(RA8875_INTC2, RA8875_INT_TP);                            // reg RA8875_INTC2: Clear any TP interrupt flag
         touchSample = 0;
         touchState = no_cal;
-        //touchTicker.attach_us(callback(this, &RA8875::_TouchTicker), TOUCH_TICKER_uS);
+#if 0
         #if (MBED_MAJOR_VERSION >= 5) || (MBED_LIBRARY_VERSION > 127)
         touchTicker.attach_us(callback(this, &RA8875::_TouchTicker), TOUCH_TICKER_uS);
         #else
         touchTicker.attach_us(this, &RA8875::_TouchTicker, TOUCH_TICKER_uS);
         #endif
-
+#endif
         timeSinceTouch.start();
         timeSinceTouch.reset();
         r = _internal_ts_cal();
@@ -103,12 +103,12 @@
                 !(bTpAdcSampleTime <= TP_ADC_SAMPLE_65536_CLKS) \
           ) return bad_parameter;
         // Construct the config byte for TPCR0 and write them
-        WriteCommand(TPCR0, bTpEnable | bTpAdcClkDiv | bTpAdcSampleTime);    // Note: Wakeup is never enabled
+        WriteCommand(RA8875_TPCR0, bTpEnable | bTpAdcClkDiv | bTpAdcSampleTime);    // Note: Wakeup is never enabled
         // Construct the config byte for TPCR1 and write them
-        WriteCommand(TPCR1, bTpDebounce | bTpManualMode);    // Note: Always uses internal Vref.
+        WriteCommand(RA8875_TPCR1, bTpDebounce | bTpManualMode);    // Note: Always uses internal Vref.
         // 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
+        WriteCommand(RA8875_INTC1, ReadCommand(RA8875_INTC1) | RA8875_INT_TP);        // reg RA8875_INTC1: Enable Touch Panel Interrupts (D2 = 1)
+        WriteCommand(RA8875_INTC2, RA8875_INT_TP);                            // reg RA8875_INTC2: Clear any TP interrupt flag
         touchSample = 0;
         touchState = no_cal;
         if (bTpEnable == TP_ENABLE) {
@@ -297,15 +297,21 @@
     TouchCode_t ts = no_touch;
 
     if (useTouchPanel == TP_FT5206) {
-        ;
+        INFO("TP_FT5206");
     } else if (useTouchPanel == TP_GSL1680) {
-        ;
+        INFO("TP_GSL1680");
     } else if (useTouchPanel == TP_RES) {
         int a2dX = 0;
         int a2dY = 0;
 
         touchInfo[0].touchID = 0;
         ts = TouchPanelA2DFiltered(&a2dX, &a2dY);
+        #ifdef DEBUG
+        static TouchCode_t tsLast;
+        if (tsLast != ts)
+            INFO("ts: %d", ts);
+        tsLast = ts;
+        #endif
         if (ts != no_touch) {
             panelTouched = true;
             numberOfTouchPoints = 1;
@@ -336,8 +342,13 @@
         if (TouchPoint) {
             *TouchPoint = TranslateOrientation(touchInfo[0].coordinates);
             ts = touchInfo[0].touchCode;
+            #ifdef DEBUG
+            static TouchCode_t lastTS = no_touch;
+            if (lastTS != ts)
             INFO("Touch[0] %2d (%4d,%4d)", touchInfo[0].touchCode,
                 touchInfo[0].coordinates.x, touchInfo[0].coordinates.y);
+            lastTS = ts;
+            #endif
         } else {
             ts = touch;
         }
@@ -407,7 +418,7 @@
             newPoint.y = rawPoint.x;
             break;
     }
-    INFO("Translate(%3d x %3d) => (%3d x %3d)", rawPoint.x, rawPoint.y, newPoint.x, newPoint.y);
+    //INFO("Translate(%3d x %3d) => (%3d x %3d)", rawPoint.x, rawPoint.y, newPoint.x, newPoint.y);
     #endif
     return newPoint;
 }
@@ -453,10 +464,13 @@
     INFO("_TouchTicker()");
     if (timeSinceTouch.read_us() > NOTOUCH_TIMEOUT_uS) {
         touchSample = 0;
-        if (touchState == held)
+        if (touchState == held) {
             touchState = release;
-        else
+            INFO("release %d", touchState);
+        } else {
+            INFO("!= held %d", touchState);
             touchState = no_touch;
+        }
         timeSinceTouch.reset();
     }
 }
@@ -464,14 +478,17 @@
 TouchCode_t RA8875::TouchPanelA2DRaw(int *x, int *y)
 {
     INFO("A2Raw");
-    if( (ReadCommand(INTC2) & RA8875_INT_TP) ) {        // Test for TP Interrupt pending in register INTC2
+    if( (ReadCommand(RA8875_INTC2) & RA8875_INT_TP) ) {        // Test for TP Interrupt pending in register RA8875_INTC2
         INFO("Int pending");
         timeSinceTouch.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]
-        INFO("(x,y) = (%d,%d)", x, y);
-        WriteCommand(INTC2, RA8875_INT_TP);            // reg INTC2: Clear that TP interrupt flag
+        *y = ReadCommand(RA8875_TPYH) << 2 | ( (ReadCommand(RA8875_TPXYL) & 0xC) >> 2 );   // D[9:2] from reg RA8875_TPYH, D[1:0] from reg RA8875_TPXYL[3:2]
+        *x = ReadCommand(RA8875_TPXH) << 2 | ( (ReadCommand(RA8875_TPXYL) & 0x3)      );   // D[9:2] from reg RA8875_TPXH, D[1:0] from reg RA8875_TPXYL[1:0]
+        INFO("(x,y) = (%d,%d)", *x, *y);
+        WriteCommand(RA8875_INTC2, RA8875_INT_TP);            // reg RA8875_INTC2: Clear that TP interrupt flag
         touchState = touch;
+    } else if (ReadCommand(RA8875_TPXYL) & RA8875_TPXYL_ADET) {
+        INFO("held");
+        touchState = held;
     } else {
         INFO("no touch");
         touchState = no_touch;
@@ -486,42 +503,19 @@
     int i, j;
     TouchCode_t ret = touchState;
 
-    if( (ReadCommand(INTC2) & RA8875_INT_TP) ) {        // Test for TP Interrupt pending in register INTC2
+    if ( (ReadCommand(RA8875_INTC2) & RA8875_INT_TP) ) {        // Test for TP Interrupt pending in register RA8875_INTC2
         timeSinceTouch.reset();
         // Get the next data samples
-        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]
+        ybuf[touchSample] =  ReadCommand(RA8875_TPYH) << 2 | ( (ReadCommand(RA8875_TPXYL) & 0xC) >> 2 );   // D[9:2] from reg RA8875_TPYH, D[1:0] from reg RA8875_TPXYL[3:2]
+        xbuf[touchSample] =  ReadCommand(RA8875_TPXH) << 2 | ( (ReadCommand(RA8875_TPXYL) & 0x3)      );   // D[9:2] from reg RA8875_TPXH, D[1:0] from reg RA8875_TPXYL[1:0]
         // Check for a complete set
         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];
-                j = i;
-                while( j && (ybuf[j-1] > temp) ) {
-                    ybuf[j] = ybuf[j-1];
-                    j = j-1;
-                }
-                ybuf[j] = temp;
-            } // End of Y sort
-            // Sort the X buffer the same way
-            for(i = 1; i <= TPBUFSIZE; i++) {
-                temp = xbuf[i];
-                j = i;
-                while( j && (xbuf[j-1] > temp) ) {
-                    xbuf[j] = xbuf[j-1];
-                    j = j-1;
-                }
-                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++ ) {
@@ -535,10 +529,13 @@
             }
             *x = lastX = j * (float)2/TPBUFSIZE;    // This is the average
             // Tidy up and return
-            if (touchState == touch || touchState == held)
+            if (touchState == touch || touchState == held) {
                 touchState = held;
-            else
+                INFO("held");
+            } else {
                 touchState = touch;
+                INFO("touch");
+            }
             ret = touchState;
             touchSample = 0;             // Ready to start on the next set of data samples
         } else {
@@ -546,22 +543,54 @@
             if (touchState == touch || touchState == held) {
                 *x = lastX;
                 *y = lastY;
+                {
+                    static TouchCode_t lastTC = no_touch;
+                    if (lastTC != touchState)
+                        INFO("held");
+                    lastTC = touchState;
+                }
                 ret = touchState = held;
+            } else {
+                INFO("else %d, %d", touchState, touchSample);
             }
         }
-        WriteCommand(INTC2, RA8875_INT_TP);            // reg INTC2: Clear that TP interrupt flag
-    } // End of initial if -- data has been read and processed
-    else {
+        WriteCommand(RA8875_INTC2, RA8875_INT_TP);            // reg RA8875_INTC2: Clear that TP interrupt flag
+    } else if (0 == (ReadCommand(RA8875_TPXYL) & RA8875_TPXYL_ADET)) {
+        INFO("held");
+        *x = lastX;
+        *y = lastY;
+        ret = touchState = held;
+    } else if (timeSinceTouch.read_ms() < 20) {
+        *x = lastX;
+        *y = lastY;
+        //ret = touchState;
+    } else {
+        //INFO("touchState %d", touchState);
+        //touchSample = 0;
+        *x = lastX;
+        *y = lastY;
+        if (touchState == no_touch || touchState == release) {
+            ret = touchState = no_touch;
+        } else {
+            INFO("release");
+            touchSample = 0;
+            touchState = no_touch;
+            ret = release;
+        }
+#if 0
         if (touchState == touch || touchState == held) {
             *x = lastX;
             *y = lastY;
             ret = touchState = held;
+            INFO("held");
         } else if (touchState == release) {
             *x = lastX;
             *y = lastY;
             ret = release;
             touchState = no_touch;
+            INFO("release");
         }
+#endif
     }
     return ret;
 }