![](/media/cache/profiles/elmicro_favicon-260x260.png.50x50_q85.jpg)
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).
touch.cpp
- Committer:
- elmicro
- Date:
- 2012-06-28
- Revision:
- 0:db0d63650413
File content as of revision 0:db0d63650413:
#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! }