Fork of David Smart's RA8875 library for the purpose of adding touch screen support
Fork of RA8875 by
Revision 54:e117ad10fba6, committed 2014-03-23
- 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