Fork of David Smart's RA8875 library for the purpose of adding touch screen support

Fork of RA8875 by David Smart

Revision:
54:e117ad10fba6
Parent:
53:86d24b9480b9
--- a/RA8875.cpp	Mon Mar 17 11:29:40 2014 +0000
+++ b/RA8875.cpp	Sun Mar 23 17:35:14 2014 +0000
@@ -118,6 +118,119 @@
     return noerror;
 }
 
+// ### Touch Panel support code additions begin here
+
+RetCode_t RA8875::TouchPanelInit(void)
+{        
+    //TPCR0: Set enable bit, default sample time, wakeup, and ADC clock
+    WriteCommand(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
+    return noerror;
+}
+
+RetCode_t RA8875::TouchPanelInit(uint8_t bTpEnable, uint8_t bTpAutoManual, uint8_t bTpDebounce, uint8_t bTpManualMode, uint8_t bTpAdcClkDiv, uint8_t bTpAdcSampleTime)
+{
+    // Parameter bounds check
+    if( \
+        !(bTpEnable == TP_ENABLE || bTpEnable == TP_ENABLE) || \
+        !(bTpAutoManual == TP_MODE_AUTO || bTpAutoManual == TP_MODE_MANUAL) || \
+        !(bTpDebounce == TP_DEBOUNCE_OFF || bTpDebounce == TP_DEBOUNCE_ON) || \
+        !(bTpManualMode <= TP_MANUAL_LATCH_Y) || \
+        !(bTpAdcClkDiv <= TP_ADC_CLKDIV_128) || \
+        !(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
+    // Construct the config byte for TPCR1 and write them
+    WriteCommand(TPCR1, bTpManualMode | 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
+    return noerror;    
+}
+
+unsigned char RA8875::TouchPanelRead(loc_t *x, loc_t *y)
+{
+    unsigned char touchready;
+    static int xbuf[TPBUFSIZE], ybuf[TPBUFSIZE], sample = 0;
+    int i, j, temp;
+
+    if( (ReadCommand(INTC2) & RA8875_INT_TP) ) {        // Test for TP Interrupt pending in register INTC2    
+        // 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]
+        // Check for a complete set
+        if(++sample == 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.
+           
+           // 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
+            // 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
+            // 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           
+            // Tidy up and return 
+            touchready = 1;
+            sample = 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;
+        }
+        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;
+}
+
+unsigned char RA8875::TouchPanelReadRaw(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;
+}
+// #### end of touch panel code additions
 
 #ifdef PERF_METRICS
 void RA8875::ClearPerformance()