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

Fork of RA8875 by David Smart

Files at this revision

API Documentation at this revision

Comitter:
hexley
Date:
Sun Mar 23 17:35:14 2014 +0000
Parent:
53:86d24b9480b9
Commit message:
Includes both raw and filtered TP outputs.

Changed in this revision

RA8875.cpp Show annotated file Show diff for this revision Revisions of this file
RA8875.h Show annotated file Show diff for this revision Revisions of this file
--- 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()
--- a/RA8875.h	Mon Mar 17 11:29:40 2014 +0000
+++ b/RA8875.h	Sun Mar 23 17:35:14 2014 +0000
@@ -121,6 +121,13 @@
         FloatingWindow      ///< Floating Window mode
     } LayerMode_T;
     
+    /// Touch Panel modes
+    typedef enum
+    {
+        TP_Auto,               ///< Auto touch detection mode
+        TP_Manual,             ///< Manual touch detection mode
+    } tpmode_t;
+    
     /// Constructor for a display based on the RAiO RA8875 
     /// display controller.
     ///
@@ -192,7 +199,86 @@
     /// @returns success/failure code. @see RetCode_t.
     ///
     RetCode_t SetBackgroundTransparencyColor(color_t color = RGB(0,0,0));
+ 
+    /// Initialize theTouch Panel controller with default values 
+    ///
+    /// @returns success/failure code. @see RetCode_t.   
+    RetCode_t TouchPanelInit(void);
+        
+    /// Initialize the Touch Panel controller with detailed settings.
+    ///
+    ///
+    /// @param[in]  bTpEnable           Touch Panel enable/disable control:
+    ///                                 - TP_ENABLE: enable the touch panel
+    ///                                 - TP_DISABLE: disable the touch panel
+    ///             bTpAutoManual       Touch Panel operating mode:
+    ///                                 - TP_MODE_AUTO: automatic capture
+    ///                                 - TP_MODE_MANUAL: manual capture
+    ///             bTpDebounce         Debounce circuit enable for touch panel interrupt:
+    ///                                 - TP_DEBOUNCE_OFF: disable the debounce circuit
+    ///                                 - TP_DEBOUNCE_ON: enable the debounce circuit     
+    ///             bTpManualMode       When Manual Mode is selected, this sets the mode:
+    ///                                 - TP_MANUAL_IDLE: touch panel is idle   
+    ///                                 - TP_MANUAL_WAIT: wait for touch panel event   
+    ///                                 - TP_MANUAL_LATCH_X: latch X data  
+    ///                                 - TP_MANUAL_LATCH_Y: latch Y data   
+    ///             bTpAdcClkDiv        Sets the ADC clock as a fraction of the System CLK:
+    ///                                 - TP_ADC_CLKDIV_1: Use CLK   
+    ///                                 - TP_ADC_CLKDIV_2: Use CLK/2   
+    ///                                 - TP_ADC_CLKDIV_4: Use CLK/4   
+    ///                                 - TP_ADC_CLKDIV_8: Use CLK/8   
+    ///                                 - TP_ADC_CLKDIV_16: Use CLK/16   
+    ///                                 - TP_ADC_CLKDIV_32: Use CLK/32   
+    ///                                 - TP_ADC_CLKDIV_64: Use CLK/64   
+    ///                                 - TP_ADC_CLKDIV_128: Use CLK/128   
+    ///             bTpAdcSampleTime    Touch Panel sample time delay before ADC data is ready:
+    ///                                 - TP_ADC_SAMPLE_512_CLKS: Wait 512 system clocks   
+    ///                                 - TP_ADC_SAMPLE_1024_CLKS: Wait 1024 system clocks   
+    ///                                 - TP_ADC_SAMPLE_2048_CLKS: Wait 2048 system clocks   
+    ///                                 - TP_ADC_SAMPLE_4096_CLKS: Wait 4096 system clocks   
+    ///                                 - TP_ADC_SAMPLE_8192_CLKS: Wait 8192 system clocks   
+    ///                                 - TP_ADC_SAMPLE_16384_CLKS: Wait 16384 system clocks   
+    ///                                 - TP_ADC_SAMPLE_32768_CLKS: Wait 32768 system clocks   
+    ///                                 - TP_ADC_SAMPLE_65536_CLKS: Wait 65536 system clocks
+    /// @returns success/failure code. @see RetCode_t.         
+    RetCode_t TouchPanelInit(uint8_t bTpEnable, uint8_t bTpAutoManual, uint8_t bTpDebounce, uint8_t bTpManualMode, uint8_t bTpAdcClkDiv, uint8_t bTpAdcSampleTime);
     
+    /// Poll the TouchPanel and on a touch event return the filtered x, y coordinates.
+    ///
+    /// @param x,y  
+    unsigned char TouchPanelRead(loc_t *x, loc_t *y);
+
+    /// Poll the TouchPanel and on a touch event return the raw x, y coordinates.
+    ///
+    /// @param x,y
+    unsigned char TouchPanelReadRaw(loc_t *x, loc_t *y);
+    
+    /// Append interrupt handler for specific RA8875 interrupt source
+    ///
+    /// @param[in]    bISRType        Interrupt Source, should be:
+    ///                                - RA8875_INT_KEYSCAN: KEYCAN interrupt
+    ///                                - RA8875_INT_DMA: DMA interrupt
+    ///                                - RA8875_INT_TP: Touch panel interrupt
+    ///                                - RA8875_INT_BTE: BTE process complete interrupt
+    ///                                - RA8875_INT_BTEMCU_FONTWR: Multi-purpose interrupt (see spec sheet)   
+    ///                               
+    /// @return       none
+    ///
+    void AppendISR(uint8_t bISRType, void(*fptr)(void));
+
+    /// Unappend interrupt handler for specific RA8875 interrupt source
+    ///
+    /// @param[in]    bISRType        Interrupt Source, should be:
+    ///                                - RA8875_INT_KEYSCAN: KEYCAN interrupt
+    ///                                - RA8875_INT_DMA: DMA interrupt
+    ///                                - RA8875_INT_TP: Touch panel interrupt
+    ///                                - RA8875_INT_BTE: BTE process complete interrupt
+    ///                                - RA8875_INT_BTEMCU_FONTWR: Multi-purpose interrupt (see spec sheet)   
+    ///                               
+    /// @return       none
+    ///
+    void UnAppendISR(uint8_t bISRType);
+
     /// Write a command to the display with a word of data.
     ///
     /// This is a high level command, and may invoke several primitives.
@@ -943,7 +1029,76 @@
     void ReportPerformance(Serial & pc);
 #endif
 
+// Touch Panel public macros
+
+/* Touch Panel Enable/Disable Reg TPCR0[7] */
+#define TP_ENABLE   ((uint8_t)(1<<7))
+#define TP_DISABLE  ((uint8_t)(0<<7))
+
+/* Touch Panel operating mode Reg TPCR1[6] */
+#define TP_MODE_AUTO    ((uint8_t)(0<<6))   
+#define TP_MODE_MANUAL  ((uint8_t)(1<<6))
+
+/* Touch Panel debounce Reg TPCR1[2]    */
+#define TP_DEBOUNCE_OFF ((uint8_t)(0<<2))
+#define TP_DEBOUNCE_ON  ((uint8_t)(1<<2))
+
+/* Touch Panel manual modes Reg TPCR1[1:0]  */
+#define TP_MANUAL_IDLE      0
+#define TP_MANUAL_WAIT      1
+#define TP_MANUAL_LATCH_X   2
+#define TP_MANUAL_LATCH_Y   3
+
+/* Touch Panel ADC Clock modes Reg TPCR0[2:0] */
+#define TP_ADC_CLKDIV_1            0
+#define TP_ADC_CLKDIV_2            1        
+#define TP_ADC_CLKDIV_4            2        
+#define TP_ADC_CLKDIV_8            3      
+#define TP_ADC_CLKDIV_16           4        
+#define TP_ADC_CLKDIV_32           5        
+#define TP_ADC_CLKDIV_64           6        
+#define TP_ADC_CLKDIV_128          7
+        
+
+/* Touch Panel Sample Time Reg TPCR0[6:4] */
+#define TP_ADC_SAMPLE_512_CLKS     ((uint8_t)(0<<4))
+#define TP_ADC_SAMPLE_1024_CLKS    ((uint8_t)(1<<4))
+#define TP_ADC_SAMPLE_2048_CLKS    ((uint8_t)(2<<4))
+#define TP_ADC_SAMPLE_4096_CLKS    ((uint8_t)(3<<4))
+#define TP_ADC_SAMPLE_8192_CLKS    ((uint8_t)(4<<4))
+#define TP_ADC_SAMPLE_16384_CLKS   ((uint8_t)(5<<4))
+#define TP_ADC_SAMPLE_32768_CLKS   ((uint8_t)(6<<4))
+#define TP_ADC_SAMPLE_65536_CLKS   ((uint8_t)(7<<4))
+
+/* RA8875 interrupt enable/flag/clear masks */
+#define RA8875_INT_KEYSCAN          ((uint8_t)(1<<4))    /**< KEYSCAN interrupts  */
+#define RA8875_INT_DMA              ((uint8_t)(1<<3))    /**< DMA interrupts  */
+#define RA8875_INT_TP               ((uint8_t)(1<<2))    /**< Touch panel interrupts  */
+#define RA8875_INT_BTE              ((uint8_t)(1<<1))    /**< BTE process complete interrupts  */
+#define RA8875_INT_BTEMCU_FONTWR    ((uint8_t)(1<<0))    /**< BTE-MCU-R/W or Font-Write interrupts  */
+
+
 private:
+    /// Touch Panel register name definitions
+#define TPCR0   0x70
+#define TPCR1   0x71
+#define TPXH    0x72
+#define TPYH    0x73
+#define TPXYL   0x74
+#define INTC1   0xF0
+#define INTC2   0xF1
+
+    /// Specify the default settings for the Touch Panel, where different from the chip defaults
+#define TP_MODE_DEFAULT             TP_MODE_AUTO
+#define TP_DEBOUNCE_DEFAULT         TP_DEBOUNCE_ON
+#define TP_ADC_CLKDIV_DEFAULT       TP_ADC_CLKDIV_8
+
+#define TP_ADC_SAMPLE_DEFAULT_CLKS  TP_ADC_SAMPLE_8192_CLKS
+
+    /// Other Touch Panel params
+#define TPBUFSIZE   16       // Depth of the averaging buffers for x and y data
+
+
     /// Set the SPI port frequency (in Hz).
     ///
     /// @note attempts to call this API at runtime, with the display