Forked para SNOCC
Fork of RA8875 by
Diff: RA8875_Touch.cpp
- Revision:
- 83:7bad0068cca0
- Parent:
- 81:01da2e34283d
- Child:
- 85:022bba13c5c4
--- a/RA8875_Touch.cpp Tue Dec 30 23:45:37 2014 +0000 +++ b/RA8875_Touch.cpp Thu Jan 01 20:35:37 2015 +0000 @@ -3,6 +3,9 @@ #include "RA8875.h" +#define NOTOUCH_TIMEOUT_uS 100000 +#define TOUCH_TICKER_uS 1000 + // ### Touch Panel support code additions begin here RetCode_t RA8875::TouchPanelInit(void) @@ -13,6 +16,11 @@ 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 + touchSample = 0; + touchState = no_cal; + touchTicker.attach_us(this, &RA8875::_TouchTicker, TOUCH_TICKER_uS); + touchTimer.start(); + touchTimer.reset(); return noerror; } @@ -34,6 +42,16 @@ // 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 + touchSample = 0; + touchState = no_cal; + if (bTpEnable == TP_ENABLE) { + touchTicker.attach_us(this, &RA8875::_TouchTicker, TOUCH_TICKER_uS); + touchTimer.start(); + touchTimer.reset(); + } else { + touchTicker.detach(); + touchTimer.stop(); + } return noerror; } @@ -60,8 +78,10 @@ { point_t pTest[3]; point_t pSample[3]; - loc_t x,y; + int x,y; + while (TouchPanelA2DFiltered(&x, &y)) + wait_ms(20); cls(); if (msg) puts(msg); @@ -145,32 +165,32 @@ * operations to scale results by a factor of 2 or even 4. * */ -bool RA8875::TouchPanelReadable(point_t * TouchPoint) +TouchCode_t RA8875::TouchPanelReadable(point_t * TouchPoint) { - bool touched = false; - point_t screenpoint = {0, 0}; + int a2dX = 0; + int a2dY = 0; - if (TouchPanelA2DFiltered(&screenpoint.x, &screenpoint.y)) { - touched = true; + TouchCode_t ts = TouchPanelA2DFiltered(&a2dX, &a2dY); + if (ts != no_touch) { if (tpMatrix.Divider != 0 && TouchPoint) { /* Operation order is important since we are doing integer */ /* math. Make sure you add all terms together before */ /* dividing, so that the remainder is not rounded off */ /* prematurely. */ - TouchPoint->x = ( (tpMatrix.An * screenpoint.x) + - (tpMatrix.Bn * screenpoint.y) + + TouchPoint->x = ( (tpMatrix.An * a2dX) + + (tpMatrix.Bn * a2dY) + tpMatrix.Cn ) / tpMatrix.Divider ; - TouchPoint->y = ( (tpMatrix.Dn * screenpoint.x) + - (tpMatrix.En * screenpoint.y) + + TouchPoint->y = ( (tpMatrix.Dn * a2dX) + + (tpMatrix.En * a2dY) + tpMatrix.Fn ) / tpMatrix.Divider ; } else { - touched = false; + ts = no_cal; } } - return touched; + return ts; } @@ -179,27 +199,76 @@ if (matrixPtr == NULL || matrixPtr->Divider == 0) return bad_parameter; memcpy(&tpMatrix, matrixPtr, sizeof(tpMatrix_t)); + touchState = no_touch; return noerror; } -bool RA8875::TouchPanelA2DFiltered(loc_t *x, loc_t *y) +static void InsertionSort(int * buf, int bufsize) +{ + int i, j; + int temp; + + for(i = 1; i <= bufsize; i++) { + temp = buf[i]; + j = i; + while( j && (buf[j-1] > temp) ) { + buf[j] = buf[j-1]; + j = j-1; + } + buf[j] = temp; + } // End of sort +} + + +void RA8875::_TouchTicker(void) { - unsigned char touchready; - static int xbuf[TPBUFSIZE], ybuf[TPBUFSIZE], sample = 0; - int i, j, temp; + if (touchTimer.read_us() > NOTOUCH_TIMEOUT_uS) { + touchSample = 0; + if (touchState == held) + touchState = release; + else + touchState = no_touch; + touchTimer.reset(); + } +} + +TouchCode_t RA8875::TouchPanelA2DRaw(int *x, int *y) +{ + if( (ReadCommand(INTC2) & RA8875_INT_TP) ) { // Test for TP Interrupt pending in register INTC2 + touchTimer.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] + WriteCommand(INTC2, RA8875_INT_TP); // reg INTC2: Clear that TP interrupt flag + touchState = touch; + } else { + touchState = no_touch; + } + return touchState; +} + +TouchCode_t RA8875::TouchPanelA2DFiltered(int *x, int *y) +{ + static int xbuf[TPBUFSIZE], ybuf[TPBUFSIZE]; + static int lastX, lastY; + int i, j; + TouchCode_t ret = touchState; if( (ReadCommand(INTC2) & RA8875_INT_TP) ) { // Test for TP Interrupt pending in register INTC2 + touchTimer.reset(); // 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] + 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] // Check for a complete set - if(++sample == TPBUFSIZE) { + 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]; @@ -220,44 +289,49 @@ } 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++ ) { j += ybuf[i]; } - *y = j * (float)2/TPBUFSIZE; // This is the average + *y = lastY = 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 + *x = lastX = 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 + if (touchState == touch || touchState == held) + touchState = held; + else + touchState = touch; + ret = touchState; + touchSample = 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; + if (touchState == touch || touchState == held) { + *x = lastX; + *y = lastY; + ret = touchState = held; + } } 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; -} - -bool RA8875::TouchPanelA2DRaw(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; + else { + if (touchState == touch || touchState == held) { + *x = lastX; + *y = lastY; + ret = touchState = held; + } else if (touchState == release) { + *x = lastX; + *y = lastY; + ret = release; + touchState = no_touch; + } + } + return ret; } /* The following section is derived from Carlos E. Vidales. @@ -451,6 +525,7 @@ tpMatrix.Fn = (screenPtr[2].x * displayPtr[1].y - screenPtr[1].x * displayPtr[2].y) * screenPtr[0].y + (screenPtr[0].x * displayPtr[2].y - screenPtr[2].x * displayPtr[0].y) * screenPtr[1].y + (screenPtr[1].x * displayPtr[0].y - screenPtr[0].x * displayPtr[1].y) * screenPtr[2].y ; + touchState = no_touch; if (matrixPtr) memcpy(matrixPtr, &tpMatrix, sizeof(tpMatrix_t)); }