Library files for using Seeed Studio TFT Touch Shield for Arduino (ST7781R controller) together with ELMICRO TestBed for mbed. Featuring a short example program of how to calibrate the touch screen. Some basic drawing functions are also included (circle, rectangle, lines, text).
Diff: touch.cpp
- Revision:
- 0:db0d63650413
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/touch.cpp Thu Jun 28 10:12:07 2012 +0000 @@ -0,0 +1,251 @@ +#include <LPC17xx.h> +#include "touch.h" +#include "shortcuts.h" + +struct tinit TFTData; + +void TouchInit(void) +{ + LPC_SC->PCONP |= (BIT12); //Enable power to ADC block + LPC_ADC->ADCR = BIT8 | //ADC clock is (25MHz/5) + BIT21; //enable ADC +} + +/* =================================================================== + routine: GetPressure + purpose: Hardware driver for sampling the touch screen using + four ADC-channels + parameters: none + returns: raw value from ADC corresponding to pressure of + touch input + note: "Pressure" actually means how much display area is + supposed to pressure + date: 2012-06-27 + author: Stefan Guenther + Elektronikladen | ELMICRO + -------------------------------------------------------------------*/ +unsigned int GetPressure(void) +{ + int tmp; + + LPC_PINCON->PINSEL1 &= ~0x4000; //Y- + LPC_PINCON->PINSEL1 |= 0x10000; //X- + LPC_PINCON->PINSEL1 |= 0x40000; //Y+ + LPC_PINCON->PINSEL1 &= ~0x100000; //X+ + LPC_GPIO0->FIODIR |= BIT23|BIT26; //X- and Y+ as output + LPC_GPIO0->FIOCLR = BIT23; //X- is GND + LPC_GPIO0->FIOSET = BIT26; //Y+ is VCC (3V3) + LPC_ADC->ADCR &= ~0xFF; + LPC_ADC->ADCR |= BIT1; //set X- as ADC input + LPC_ADC->ADCR |= BIT24; //start sampling + while(!(LPC_ADC->ADGDR&BIT31)); //wait for ADC + + tmp = (LPC_ADC->ADGDR&0xFFF0)>>4; //store ADC value + LPC_ADC->ADCR &= ~0xFF; + LPC_ADC->ADCR |= BIT2; //set Y+ as ADC input + LPC_ADC->ADCR |= BIT24; //start another ADC sampling + while(!(LPC_ADC->ADGDR&BIT31)); //wait for it + + //calculate pressure value out of the two samples + //and invert it by subtracting from 2^12 + return(4096 - (tmp - ( (LPC_ADC->ADGDR&0xFFF0) >>4 ) ) ); +} + + +/* =================================================================== + routine: GetTouchX + purpose: Hardware driver for sampling the touch screen using + four ADC-channels + parameters: none + returns: raw value from ADC corresponding to X coordinate of + touch input + date: 2012-06-27 + author: Stefan Guenther + Elektronikladen | ELMICRO + -------------------------------------------------------------------*/ +unsigned int GetTouchX(void) +{ + LPC_PINCON->PINSEL1 |= 0x4000; //connects to Y- signal + LPC_PINCON->PINSEL1 &= ~0x10000; // X- + LPC_PINCON->PINSEL1 |= 0x40000; // Y+ + LPC_PINCON->PINSEL1 &= ~0x100000; // X+ + LPC_GPIO0->FIODIR |= BIT24|BIT26; //X+ and X- as output + LPC_GPIO0->FIOCLR = BIT24; //X- set to GND + LPC_GPIO0->FIOSET = BIT26; //X+ set to VCC (3V3) + LPC_ADC->ADCR &= ~0xFF; //clear active ADC channel information + LPC_ADC->ADCR |= BIT2; //set Y- as active ADC channel + LPC_ADC->ADCR |= BIT24; //start ADC sampling + while(!(LPC_ADC->ADGDR&BIT31)); //wait until ADC completes operation + + return((LPC_ADC->ADGDR&0xFFF0)>>4); //extract the 12bit-information +} + + +/* =================================================================== + routine: GetTouchY + purpose: Hardware driver for sampling the touch screen using + four ADC-channels + parameters: none + returns: raw value from ADC corresponding to Y coordinate of + touch input + date: 2012-06-27 + author: Stefan Guenther + Elektronikladen | ELMICRO + -------------------------------------------------------------------*/ +unsigned int GetTouchY(void) +{ + LPC_PINCON->PINSEL1 &= ~0x4000; //Y- + LPC_PINCON->PINSEL1 |= 0x10000; //X- + LPC_PINCON->PINSEL1 &= ~0x40000; //Y+ + LPC_PINCON->PINSEL1 |= 0x100000; //X+ + LPC_GPIO0->FIODIR |= BIT23|BIT25; //Y+ and Y- as output + LPC_GPIO0->FIOCLR = BIT23; + LPC_GPIO0->FIOSET = BIT25; + LPC_ADC->ADCR &= ~0xFF; + LPC_ADC->ADCR |= BIT3; + LPC_ADC->ADCR |= BIT24; + while(!(LPC_ADC->ADGDR&BIT31)); + + return((LPC_ADC->ADGDR&0xFFF0)>>4); +} + + +/* =================================================================== + routine: GetRawTouch + purpose: Reads input values from Touchscreen without + processing them (mainly useful for doing a calibration) + parameters: <*x,y,z> pointers to coordinate variables + returns: 1 if touch was recognized + 0 if no touch occured + note: For code explanation, look the GetPoint() function + date: 2012-06-27 + author: Stefan Guenther + Elektronikladen | ELMICRO + -------------------------------------------------------------------*/ +unsigned char GetRawTouch(unsigned int *x, unsigned int *y, unsigned int *z) +{ + unsigned int x1, x2, y1, y2, z1, z2; + + z1 = GetPressure(); + + if(z1>1500) + { + x1 = GetTouchX(); + y1 = GetTouchY(); + + z2 = GetPressure(); + if(z2>1500) + { + x2 = GetTouchX(); + y2 = GetTouchY(); + + if( ( (x1>x2-20) && (x1<x2+20) ) && ( (y1>y2-20) && (y1<y2+20) ) ) + { + *x = (x1+x2) / 2; + *y = (y1+y2) / 2; + *z = (z1+z2) / 2; + + return 1; + } + } + } + return 0; +} + + +/* =================================================================== + routine: MapX + purpose: Maps/alligns X-coordinate of touch input onto LCD's + pixel grid + parameters: <x> touch coordinate + returns: pixel coordinate of touch input + date: 2012-06-27 + author: Stefan Guenther + Elektronikladen | ELMICRO + -------------------------------------------------------------------*/ +unsigned int MapX(unsigned int x) +{ + if(x>TFTData.Xmin) + { + x = x-TFTData.Xmin; + x = (x*1000) / TFTData.Xscale; + if(x>TFTData.XRes - 1) x = TFTData.XRes - 1; + } else { + x = 0; + } + return x; +} + + +/* =================================================================== + routine: MapY + purpose: Maps/alligns Y-coordinate of touch input onto LCD's + pixel grid + parameters: <x> touch coordinate + returns: pixel coordinate of touch input + date: 2012-06-27 + author: Stefan Guenther + Elektronikladen | ELMICRO + -------------------------------------------------------------------*/ +unsigned int MapY(unsigned int y) +{ + if(y>TFTData.Ymin) //Y input larger than the expected minimum? + { + y = y - TFTData.Ymin; //subtract offset from Y coordinate + y = (y*1000) / TFTData.Yscale; //scale according to touch screen's parameter + //(this results in an alignment between touch + //input and output pixel grid) + if(y>TFTData.YRes - 1) y = TFTData.YRes - 1; //prevent "out of pixel boundary" + } else { + y = 0; //sampled Y-coordinate was lower than touch + } //screen's expected minimum, so keep Y in boundary + return y; +} + + +/* =================================================================== + routine: GetPoint + purpose: Reads and processes touch input + parameters: <*x, *y> pointers to coordinate variables + returns: 1 if touch input was recognized + 0 if no touch occured + + note: An oversampling (x2) is done to increase noise + immunity. + A pressure value of 1500 has to be read to trigger + the further processing - a lower value could improve + touch sensitivity but also increases the risk of + sampling noise instead of touch inputs. + date: 2012-06-27 + author: Stefan Guenther + Elektronikladen | ELMICRO + -------------------------------------------------------------------*/ +unsigned char GetPoint(unsigned int *x, unsigned int *y) +{ + unsigned int x1, x2, y1, y2, z1, z2; + + z1 = GetPressure(); //check for pressure onto touch screen + if(z1>1500) //pressure above threshold? + { + x1 = MapX(GetTouchX()); //read touch coordinates + y1 = MapY(GetTouchY()); + + z2 = GetPressure(); //oversampling - start second input read + if(z2>1500) //the second pressure was also above threshold? + { + x2 = MapX(GetTouchX()); //sample again + y2 = MapY(GetTouchY()); + + /* check if both samples were nearly the same + increase the '2' to improve sensitivity */ + if( ( (x1>x2 - 2) && (x1<x2+2) ) && ( (y1>y2 - 2) && (y1<y2 + 2) ) ) + { + *x = (x1+x2) / 2; //do a simple meridian calculation + *y = (y1+y2) / 2; //on both samples and both coordinates + + return 1; //touch input was processed! + } + } + } + return 0; //no touch input was processed! +} \ No newline at end of file