Lcd companion boards support (VKLCD50RTA & VKLCD70RT)
Embed:
(wiki syntax)
Show/hide line numbers
Touch.cpp
00001 #include "Touch.h" 00002 00003 const touch_config_t STMPE811_cfg = { 00004 "STMPE811", LCD_VDC5_CH0_PANEL, RESISTIVE , 00005 {I_2_C , TPIIC_SDA, TPIIC_SCL, NC, NC, NC, NC, 100000}, 00006 {INT_ON_EDGE , FALLING_OR_ACTIVE_LO , TPIRQ_PIN} 00007 }; 00008 00009 bool Touch::new_data; 00010 00011 00012 /**************************************************************************//** 00013 * @brief Constructor of the Touch class 00014 * @param[in] pointer to Config structure (touch_config_t) 00015 ******************************************************************************/ 00016 //SPI(tp_cfg->interface.mosi, tp_cfg->interface.miso, tp_cfg->interface.sclk, tp_cfg->interface.ssel), 00017 Touch::Touch( const touch_config_t * tp_cfg ) : I2C(tp_cfg->interface.sda, tp_cfg->interface.scl), InterruptIn(tp_cfg->activity_irq.pin) 00018 { 00019 if(tp_cfg == NULL) 00020 touch_cfg = &STMPE811_cfg; 00021 else 00022 touch_cfg = tp_cfg; 00023 00024 x = y = z = 0; adc_x = adc_y = adc_z = 0; 00025 xyz_data = screen_data; adc_data = raw_data; 00026 last_xyz_idx = FIFO_DEPTH; 00027 new_data = false; 00028 calib.data.flag = 0; 00029 00030 } /* End of constructor */ 00031 00032 00033 /**************************************************************************//** 00034 * @brief Touch controller initialization 00035 * @retval error code 00036 ******************************************************************************/ 00037 Touch::init_err_t Touch::Init( void ) 00038 { 00039 init_err_t tp_err; 00040 00041 if(touch_cfg->type == RESISTIVE ) 00042 { 00043 tp_err = Clb_Setup(); 00044 00045 if(tp_err != TOUCH_OK ) 00046 return tp_err; 00047 } 00048 00049 if(touch_cfg->interface.type == I_2_C ) 00050 I2C::frequency(touch_cfg->interface.freq); 00051 //else 00052 //SPI::frequency(touch_cfg->interface.freq); 00053 00054 tp_err = Drv_Setup(); 00055 00056 if(tp_err != TOUCH_OK ) 00057 return tp_err; 00058 00059 if(touch_cfg->activity_irq.polarity == FALLING_OR_ACTIVE_LO ) 00060 { 00061 rise(NULL); 00062 fall(&Irq_Alert); 00063 } 00064 else 00065 { 00066 rise(&Irq_Alert); 00067 fall(NULL); 00068 } 00069 00070 if(tp_err == TOUCH_OK ) 00071 enable_irq(); 00072 00073 return tp_err; 00074 } /* End of method Init() */ 00075 00076 00077 /**************************************************************************//** 00078 * @brief Set Calibration data 00079 * @retval error code 00080 ******************************************************************************/ 00081 Touch::init_err_t Touch::Clb_Setup() 00082 { 00083 if(touch_cfg->name == "STMPE811") 00084 { 00085 #ifndef __USE_DEFAULT_CALIBRATION_DATA__ 00086 // extract calibration info from lcdpanel EEPROM 00087 char adr = 0; 00088 00089 if( (touch_cfg->interface.sda == EEIIC_SDA) || (touch_cfg->interface.scl == EEIIC_SCL)) 00090 { // EEPROM is on the same I2C channel no need to initialize a new one ! 00091 if(I2C::write(EE_CALIB_DEVICE_ADDR, (const char *)&adr, 1, true) != 0) 00092 return TOUCH_INIT_ERR ; 00093 if(I2C::read(EE_CALIB_DEVICE_ADDR, (char*)calib.KX08, sizeof(calib.KX08)) != 0) 00094 return TOUCH_INIT_ERR ; 00095 } 00096 else 00097 { 00098 I2C clb_eeprom(EEIIC_SDA, EEIIC_SCL); 00099 00100 clb_eeprom.frequency(100000); 00101 if(clb_eeprom.write(EE_CALIB_DEVICE_ADDR, (const char *)&adr, 1, true) != 0) 00102 return TOUCH_INIT_ERR ; 00103 if(clb_eeprom.read(EE_CALIB_DEVICE_ADDR, (char*)calib.KX08, sizeof(calib.KX08)) != 0) 00104 return TOUCH_INIT_ERR ; 00105 } 00106 #endif 00107 00108 if(calib.data.flag != 1) 00109 { // load default calibration info 00110 unsigned char clb[] = {TPCALIBRATION_DATA}; 00111 memcpy(calib.KX08, clb, sizeof(clb)); 00112 } 00113 00114 return TOUCH_OK ; 00115 } 00116 else 00117 return TOUCH_UNSUPP_ERR ; 00118 } /* End of method Clb_Setup() */ 00119 00120 00121 /**************************************************************************//** 00122 * @brief Set Touch Controller settings 00123 * @retval error code 00124 ******************************************************************************/ 00125 Touch::init_err_t Touch::Drv_Setup() 00126 { 00127 if(touch_cfg->name == "STMPE811") 00128 { 00129 unsigned char i, initdata[][2] = { INIT_DATA }; 00130 00131 for(i=0; i<(sizeof(initdata)>>1); i++) 00132 { 00133 if(initdata[i][0] == INT_CTRL) 00134 { // reconfigure interrupt if needed 00135 initdata[i][1] = 0x01; 00136 initdata[i][1] |= (touch_cfg->activity_irq.trigger == INT_ON_EDGE )? 0x02 : 0x00; 00137 initdata[i][1] |= (touch_cfg->activity_irq.polarity == RISING_OR_ACTIVE_HI )? 0x04 : 0x00; 00138 } 00139 00140 if ((I2C::write(STMPE811_DEVICE_ADDR, (const char *)&initdata[i][0], 2)) != 0) 00141 return TOUCH_INIT_ERR ; 00142 00143 while (I2C::write(STMPE811_DEVICE_ADDR, (const char *)initdata, 0) != 0); // ACK polling 00144 } 00145 00146 return TOUCH_OK ; 00147 } 00148 else 00149 return TOUCH_UNSUPP_ERR ; 00150 } 00151 00152 00153 /**************************************************************************//** 00154 * @brief Get one sample of data 00155 * @param[in] * raw : pointer to ring buffer to store the samples 00156 ******************************************************************************/ 00157 void Touch::Get_Data( unsigned long long * raw ) 00158 { 00159 if(touch_cfg->name == "STMPE811") 00160 { 00161 int idx = last_xyz_idx; 00162 unsigned char i, packed_sample[16]; 00163 unsigned short raw_x, raw_y; 00164 unsigned char raw_z; 00165 00166 i = TSC_DATA_FIFO; 00167 I2C::write(STMPE811_DEVICE_ADDR, (const char *)&i, 1, true); 00168 I2C::read(STMPE811_DEVICE_ADDR, (char *)packed_sample, sizeof(packed_sample)); 00169 for(i=0; i<4; i++) 00170 { 00171 raw_x = (unsigned short)((packed_sample[(i*4)+0]<<4) | (packed_sample[(i*4)+1]>>4)); 00172 raw_y = (unsigned short)(((0x0F & packed_sample[(i*4)+1])<<8) | packed_sample[(i*4)+2]); 00173 raw_z = packed_sample[(i*4)+3]; 00174 00175 idx = ((idx+1) < FIFO_DEPTH)? idx+1 : 0; 00176 raw[idx] = (unsigned long long)((raw_z<<32) + (raw_y<<16) + raw_x); 00177 } 00178 } 00179 } /* End of method Get_Data() */ 00180 00181 00182 /**************************************************************************//** 00183 * @brief Get all available samples of data 00184 * @param[in] * raw : pointer to ring buffer to store the samples 00185 * @retval samples count 00186 ******************************************************************************/ 00187 int Touch::Get_Fifo( unsigned long long * raw ) 00188 { 00189 if(touch_cfg->name == "STMPE811") 00190 { 00191 int idx = last_xyz_idx; 00192 unsigned char packets; 00193 00194 packets = FIFO_SIZE; 00195 I2C::write(STMPE811_DEVICE_ADDR, (const char *)&packets, 1, true); 00196 packets = 0; 00197 I2C::read(STMPE811_DEVICE_ADDR, (char *)&packets, 1); 00198 if(packets) 00199 { 00200 unsigned char packed_sample[FIFO_DEPTH*4]; 00201 unsigned short raw_x, raw_y, i; 00202 unsigned char raw_z; 00203 00204 raw_z = TSC_DATA_FIFO; 00205 I2C::write(STMPE811_DEVICE_ADDR, (const char *)&raw_z, 1, true); 00206 I2C::read(STMPE811_DEVICE_ADDR, (char *)packed_sample, packets*4); 00207 00208 for(i=0; i<packets; i++) 00209 { 00210 raw_x = (unsigned short)((packed_sample[(i*4)+0]<<4) | (packed_sample[(i*4)+1]>>4)); 00211 raw_y = (unsigned short)(((0x0F & packed_sample[(i*4)+1])<<8) | packed_sample[(i*4)+2]); 00212 raw_z = packed_sample[(i*4)+3]; 00213 00214 idx = ((idx+1) < FIFO_DEPTH)? idx+1 : 0; 00215 raw[idx] = (raw_z<<32) + (raw_y<<16) + raw_x; 00216 } 00217 00218 return packets; 00219 } 00220 return 0; 00221 } 00222 else 00223 return 0; 00224 } /* End of method Get_Fifo() */ 00225 00226 00227 /**************************************************************************//** 00228 * @brief Coordinates Transfer function 00229 * @param[in] points : number of samples which have to become meaningful 00230 ******************************************************************************/ 00231 void Touch::Get_XYZ( int points) 00232 { 00233 if(touch_cfg->name == "STMPE811") 00234 { 00235 int i, idx; 00236 00237 for(i=0; i<points; i++) 00238 { 00239 idx = ((last_xyz_idx+1) < FIFO_DEPTH)? last_xyz_idx+1 : 0; 00240 screen_data[idx].axis.x = (signed short)(calib.data.KX1*((signed short)raw_data[idx].axis.x)+calib.data.KX2*((signed short)raw_data[idx].axis.y)+calib.data.KX3+0.5); 00241 screen_data[idx].axis.y = (signed short)(calib.data.KY1*((signed short)raw_data[idx].axis.x)+calib.data.KY2*((signed short)raw_data[idx].axis.y)+calib.data.KY3+0.5); 00242 //screen_data[idx].axis.z = 0; 00243 last_xyz_idx = idx; 00244 //printf("\r\n REC: idx-> %d", idx); 00245 //printf("\r\n TH: x-> %d, y-> %d, dots-> %d", screen_data[idx].axis.x, screen_data[idx].axis.y, idx); 00246 } 00247 00248 x = screen_data[last_xyz_idx].axis.x; adc_x = raw_data[last_xyz_idx].axis.x; 00249 y = screen_data[last_xyz_idx].axis.y; adc_y = raw_data[last_xyz_idx].axis.y; 00250 //z = screen_data[last_xyz_idx].axis.z; adc_z = raw_data[last_xyz_idx].axis.z; 00251 //printf("\r\n TH: x-> %d, y-> %d, dots-> %d", x, y, last_xyz_idx); 00252 00253 } 00254 } /* End of method Get_XYZ() */ 00255 00256 00257 /**************************************************************************//** 00258 * @brief IRQ interrupt handler : indicates "New Data available" which activates i2c data transfer in Handle_touch() 00259 ******************************************************************************/ 00260 void Touch::Irq_Alert( void ) { new_data = true; } /* End of method Irq_Alert() */ 00261 00262 00263 /**************************************************************************//** 00264 * @brief Get index of the last sample in the ring buffer 00265 * @retval idx 00266 ******************************************************************************/ 00267 int Touch::Get_Last_Idx( void ) { return last_xyz_idx; } 00268 00269 00270 /**************************************************************************//** 00271 * @brief Pull the new samples if new data is available 00272 * @param[in] * pts : pointer to a variable to put the count of the new samples 00273 * @retval Status of the pen (Stylus position up/down) 00274 ******************************************************************************/ 00275 bool Touch::Handle_touch( unsigned char *pts ) 00276 { 00277 static bool PenDown = false; 00278 unsigned char TP_IntStat = 0, rec[2]; 00279 int dots = 0; 00280 00281 *pts=0; 00282 00283 if(new_data) 00284 { 00285 TP_IntStat = INT_STA; 00286 I2C::write(STMPE811_DEVICE_ADDR, (const char *)&TP_IntStat, 1, true); 00287 TP_IntStat = 0; 00288 I2C::read(STMPE811_DEVICE_ADDR, (char *)&TP_IntStat, 1); 00289 00290 if(TP_IntStat & INT_FIFO_TH) 00291 { 00292 Get_Data(&raw_data[0].dot); 00293 Get_XYZ(4); 00294 00295 *pts = 4; 00296 00297 //Data = 1; 00298 //SET_TP_STATE(TP_FLAG_PEN_DATA_TH); 00299 //printf("\r\n TH: x-> %d, y-> %d", screen_data[3].axis.x, screen_data[3].axis.y); 00300 } 00301 00302 if(TP_IntStat & INT_TOUCH_DET) 00303 { 00304 dots = Get_Fifo(&raw_data[0].dot); 00305 if(dots) 00306 { 00307 Get_XYZ(dots); 00308 //Data = 1; 00309 //CLR_TP_STATE(TP_FLAG_PEN_DATA_TH); //SET_TP_STATE(TP_FLAG_DATA_READY); 00310 //printf("\r\n Touch Sample: x-> %d, y-> %d", screen_data[v-1].axis.x, screen_data[v-1].axis.y); 00311 } 00312 *pts = dots; 00313 00314 PenDown = (PenDown)? false : true; 00315 } 00316 00317 if(TP_IntStat & INT_FIFO_OFLOW) 00318 { 00319 rec[0] = FIFO_STA; 00320 rec[1] = 0x01; // Clear FIFO 00321 I2C::write(STMPE811_DEVICE_ADDR, (const char *)rec, 2); 00322 00323 rec[1] = 0x00; // Reset FIFO 00324 I2C::write(STMPE811_DEVICE_ADDR, (const char *)rec, 2); 00325 } 00326 00327 rec[0] = INT_STA; 00328 rec[1] = TP_IntStat; 00329 I2C::write(STMPE811_DEVICE_ADDR, (const char *)rec, 2); 00330 00331 new_data = false; 00332 } 00333 00334 return PenDown; 00335 } 00336 00337 /**************************************************************************//** 00338 * @brief Destructor of the Touch class 00339 ******************************************************************************/ 00340 Touch::~Touch( ) 00341 { 00342 touch_cfg = NULL; 00343 xyz_data = NULL; 00344 adc_data = NULL; 00345 } 00346 00347 /* End of file */ 00348
Generated on Tue Jul 12 2022 14:32:48 by
1.7.2