STMPE610 touch sensor driver library

Dependents:   TS_Eyes Tokei testUniGraphic_150217 AfficheurTFTAdafruit ... more

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers SPI_STMPE610.cpp Source File

SPI_STMPE610.cpp

00001 /* mbed SPI_STMPE610.cpp to test adafruit 2.8" TFT LCD shield w Touchscreen
00002  * Copyright (c) 2014 Motoo Tanaka @ Design Methodology Lab
00003  *
00004  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00005  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00006  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
00007  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00008  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
00009  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
00010  * THE SOFTWARE.
00011  */
00012  /*
00013   * Note: Since the interrupt siganl of the shield was not connected
00014   * to an interrupt pin on my frdm-kl25z, I just used polling mode.
00015   */
00016   /*
00017    * Note: To make this work with FRDM-K64F
00018    * PTA0 must be disconnected from the swd clk by cutting J11.
00019    * But to re-active SWD you need to put jumper header to J11
00020    * so that it can be re-connected by a jumper.
00021    */
00022 #include "SPI_STMPE610.h"
00023 
00024 /* some definitions here */
00025 #define REG_CHIP_ID       0x00
00026 #define REG_CHIP_ID_MSB   0x00
00027 #define REG_CHIP_ID_LSB   0x01
00028 
00029 #define REG_ID_VER        0x02
00030 #define REG_SYS_CTRL1     0x03
00031 #define REG_SYS_CTRL1_RESET 0x02
00032 
00033 #define REG_SYS_CTRL2     0x04
00034 #define REG_SPI_CFG       0x08
00035 #define REG_INT_CTRL      0x09
00036 #define REG_INT_CTRL_POL_HIGH 0x04
00037 #define REG_INT_CTRL_POL_LOW  0x00
00038 #define REG_INT_CTRL_EDGE     0x02
00039 #define REG_INT_CTRL_LEVEL    0x00
00040 #define REG_INT_CTRL_ENABLE   0x01
00041 #define REG_INT_CTRL_DISABLE  0x00
00042 
00043 #define REG_INT_EN        0x0A
00044 #define REG_INT_EN_TOUCHDET  0x01
00045 #define REG_INT_EN_FIFOTH    0x02
00046 #define REG_INT_EN_FIFOOF    0x04
00047 #define REG_INT_EN_FIFOFULL  0x08
00048 #define REG_INT_EN_FIFOEMPTY 0x10
00049 #define REG_INT_EN_ADC       0x40
00050 
00051 #define REG_INT_STA       0x0B
00052 #define REG_INT_STA_TOUCHDET 0x01
00053 
00054 #define REG_GPIO_EN       0x0C
00055 #define REG_GPIO_INT_STA  0x0D
00056 #define REG_ADC_INT_EN    0x0E
00057 #define REG_ADC_INT_STA   0x0F
00058 #define REG_GPIO_SET_PIN  0x10
00059 #define REG_GPIO_CLR_PIN  0x11
00060 #define REG_GPIO_MP_STA   0x12
00061 #define REG_GPIO_DIR      0x13
00062 #define REG_GPIO_ED       0x14
00063 #define REG_GPIO_RE       0x15
00064 #define REG_GPIO_FE       0x16
00065 #define REG_GPIO_AF       0x17
00066 #define REG_ADC_CTRL1     0x20
00067 #define REG_ADC_CTRL1_12BIT 0x08
00068 #define REG_ADC_CTRL1_10BIT 0x00
00069 
00070 #define REG_ADC_CTRL2     0x21
00071 #define REG_ADC_CTRL2_1_625MHZ 0x00
00072 #define REG_ADC_CTRL2_3_25MHZ  0x01
00073 #define REG_ADC_CTRL2_6_5MHZ   0x02
00074 
00075 #define REG_ADC_CAPT      0x22
00076 #define REG_ADC_DATA_CH0  0x30
00077 #define REG_ADC_DATA_CH1  0x32
00078 #define REG_ADC_DATA_CH4  0x38
00079 #define REG_ADC_DATA_CH5  0x3A
00080 #define REG_ADC_DATA_CH6  0x3C
00081 #define REG_ADC_DATA_CH7  0x3E
00082 #define REG_TSC_CTRL      0x40
00083 #define REG_TSC_CTRL_EN     0x01
00084 #define REG_TSC_CTRL_XYZ    0x00
00085 #define REG_TSC_CTRL_XY     0x02
00086 
00087 #define REG_TSC_CFG       0x41
00088 #define REG_TSC_CFG_1SAMPLE      0x00
00089 #define REG_TSC_CFG_2SAMPLE      0x40
00090 #define REG_TSC_CFG_4SAMPLE      0x80
00091 #define REG_TSC_CFG_8SAMPLE      0xC0
00092 #define REG_TSC_CFG_DELAY_10US   0x00
00093 #define REG_TSC_CFG_DELAY_50US   0x08
00094 #define REG_TSC_CFG_DELAY_100US  0x10
00095 #define REG_TSC_CFG_DELAY_500US  0x18
00096 #define REG_TSC_CFG_DELAY_1MS    0x20
00097 #define REG_TSC_CFG_DELAY_5MS    0x28
00098 #define REG_TSC_CFG_DELAY_10MS   0x30
00099 #define REG_TSC_CFG_DELAY_50MS   0x38
00100 #define REG_TSC_CFG_SETTLE_10US  0x00
00101 #define REG_TSC_CFG_SETTLE_100US 0x01
00102 #define REG_TSC_CFG_SETTLE_500US 0x02
00103 #define REG_TSC_CFG_SETTLE_1MS   0x03
00104 #define REG_TSC_CFG_SETTLE_5MS   0x04
00105 #define REG_TSC_CFG_SETTLE_10MS  0x05
00106 #define REG_TSC_CFG_SETTLE_50MS  0x06
00107 #define REG_TSC_CFG_SETTLE_100MS 0x07
00108 
00109 #define REG_WDW_TR_X      0x42
00110 #define REG_WDW_TR_Y      0x44
00111 #define REG_WDW_BL_X      0x46
00112 #define REG_WDW_BL_Y      0x48
00113 #define REG_FIFO_TH       0x4A
00114 #define REG_FIFO_STA      0x4B
00115 #define REG_FIFO_SIZE     0x4C
00116 #define REG_TSC_DATA_X    0x4D
00117 #define REG_TSC_DATA_Y    0x4F
00118 #define REG_TSC_DATA_Z    0x51
00119 #define REG_TSC_DATA_XYZ  0x52
00120 #define REG_TSC_FRACT_XYZ 0x56
00121 #define REG_TSC_DATA      0x57
00122 #define REG_TSC_I_DRIVE   0x58
00123 #define REG_TSC_SHIELD    0x59
00124 
00125 // following value are measured 
00126 // and calculated for my system
00127 // may be insufficient for other device(s)
00128 // in such case please use "calibrate()" func
00129 // to tailor the value for your device
00130 #define DEF_HRAMP   0.066667
00131 #define DEF_HOFFSET -13.333344
00132 #define DEF_VRAMP  0.094311
00133 #define DEF_VOFFSET -30.933990
00134 
00135 SPI_STMPE610::SPI_STMPE610(PinName mosi, PinName miso, PinName sclk, PinName cs) :
00136         m_spi(mosi, miso, sclk), m_cs(cs, 1) {
00137     // activate the peripheral
00138     m_cs = 0 ;
00139     _mode = 0 ;
00140     m_spi.frequency(1000000) ;
00141 #if defined (TARGET_NUCLEO_F411RE) || defined (TARGET_KL46Z) || defined (TARGET_MAX32600MBED)
00142     m_spi.format(8, 1) ; /* works with st nucleo F411RE */
00143 #else
00144     m_spi.format(8, 0) ; /* works with freescale FRDMs */
00145 #endif 
00146 
00147     write8(REG_SYS_CTRL1, REG_SYS_CTRL1_RESET) ;
00148     wait(0.1) ;
00149     write8(REG_SYS_CTRL2, 0x00) ; // turn on clocks
00150     write8(REG_TSC_CFG,
00151           REG_TSC_CFG_4SAMPLE 
00152         | REG_TSC_CFG_DELAY_100US
00153         | REG_TSC_CFG_SETTLE_1MS ) ;
00154         
00155     write8(REG_TSC_CTRL, REG_TSC_CTRL_XYZ | REG_TSC_CTRL_EN) ;   
00156     hramp   = DEF_HRAMP ;
00157     hoffset = DEF_HOFFSET ;
00158     vramp   = DEF_VRAMP ;
00159     voffset = DEF_VOFFSET ;
00160     m_cs = 1 ;
00161 }
00162 
00163 SPI_STMPE610::~SPI_STMPE610() { }
00164 
00165 void SPI_STMPE610::readRegs(int addr, uint8_t * data, int len) {
00166     m_cs = 0 ;
00167 
00168     for (int i = 0 ; i < len ; i++ ) {    
00169        m_spi.write((addr+i)|0x80) ;  // spacify address to read
00170        data[i] = m_spi.write((addr+i)|0x80) ; 
00171     } 
00172     m_spi.write(0x00) ; // to terminate read mode
00173     m_cs = 1 ;
00174 }
00175 
00176 void SPI_STMPE610::writeRegs(uint8_t * data, int len) {
00177    m_cs = 0 ;
00178    for (int i = 0 ; i < len ; i++ ) {
00179       m_spi.write(data[i]) ;
00180    }
00181    m_cs = 1 ;
00182 }
00183 
00184 void SPI_STMPE610::write8(int addr, uint8_t data8)
00185 {
00186     uint8_t data[2] ;
00187     data[0] = addr ;
00188     data[1] = data8 ;
00189     writeRegs(data, 2) ;
00190 }
00191 
00192 uint8_t SPI_STMPE610::read8(int addr)
00193 {
00194     uint8_t data[1] ;    
00195     readRegs(addr, data, 1) ;
00196     return( data[0] ) ;
00197 }
00198 
00199 void SPI_STMPE610::write16(int addr, uint16_t data16)
00200 {
00201     uint8_t data[3] ;
00202     data[0] = addr ;
00203     data[1] = (data16 >> 8) & 0xFF ;
00204     data[2] = data16 & 0xFF ;
00205     writeRegs(data, 3) ;
00206 }
00207 
00208 uint16_t SPI_STMPE610::read16(int addr)
00209 {
00210     uint8_t data[2] ;
00211     uint16_t value = 0 ;
00212     readRegs(addr, data, 2) ;
00213     value = (data[0] << 8) | data[1] ;
00214     return( value ) ;
00215 }
00216 
00217 void SPI_STMPE610::spi_frequency(unsigned long freq)
00218 {
00219     m_spi.frequency(freq) ;
00220 }
00221 
00222 void SPI_STMPE610::spi_format(int bits, int mode)
00223 {
00224     m_spi.format(bits, mode) ;
00225 }
00226 
00227 int SPI_STMPE610::getRAWPoint(uint16_t *x, uint16_t *y, uint16_t *z)
00228 {
00229     uint8_t data[8], touched = 0 ;
00230     data[0] = REG_TSC_CTRL ;
00231     data[1] = REG_TSC_CTRL_EN  ; 
00232     m_cs = 0 ;
00233     wait(0.01) ;
00234     writeRegs(data, 2) ;
00235     wait(0.01) ;
00236      
00237     readRegs(REG_TSC_CTRL, data, 1) ;
00238     touched = data[0] & 0x80 ;
00239     
00240     data[0] = 0 ; data[1] = 0 ; data[2] = 0 ; data[3] = 0 ; data[4] = 0 ;
00241 
00242     readRegs(REG_TSC_DATA_X, data,5) ;
00243         *x = (data[0] << 8) | data[1] ;
00244         *y = (data[2] << 8) | data[3] ;
00245         *z = data[4] ;
00246         
00247     data[0] = 0x4B ;
00248     data[1] = 0x01 ;
00249     writeRegs(data, 2)  ; // clear FIFO
00250  
00251     data[0] = REG_TSC_CTRL ;
00252     data[1] = 0x00 ; // disable TSC 
00253     writeRegs(data, 2) ;
00254     wait(0.01) ;
00255     m_cs = 1 ;
00256     
00257     return( touched ) ;
00258 }
00259 
00260 int SPI_STMPE610::getPoint(uint16_t *x, uint16_t *y, uint16_t *z)
00261 {
00262     uint8_t touched = 0 ;
00263     uint16_t tx, ty, tz ;
00264     
00265     touched = getRAWPoint(&tx, &ty, &tz) ;
00266     *x = (uint16_t)(hramp * tx + hoffset + 0.5) ;
00267     *y = (uint16_t)(vramp * ty + voffset + 0.5) ;
00268     if (z != 0) {
00269         *z = tz ;
00270     }
00271     return( touched ) ;
00272 }
00273 
00274 /*
00275  * logical_x = hramp * touch_x + hoffset 
00276  * logical_y = vramp * touch_y + voffset
00277  */
00278 void SPI_STMPE610::calibrate(int x_at_10, int y_at_10, int x_at_230, int y_at_310) 
00279 {
00280     hramp = (float)(230 - 10) / (float)(x_at_230 - x_at_10) ;
00281     hoffset = (float)(230) - hramp * x_at_230 ;
00282     vramp = (float)(310 - 10) / (float)(y_at_310 - y_at_10) ;
00283     voffset = (float)(310) - vramp * y_at_310 ;
00284     printf("hramp = %f , hoffset = %f\n\r", hramp, hoffset) ;
00285     printf("vramp = %f , voffset = %f\n\r", vramp, voffset) ;
00286 }