Fork of David Smart's RA8875 library for the purpose of adding touch screen support
Fork of RA8875 by
Diff: RA8875.cpp
- 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()