Touch driver for companion boards (VKLCD50RTA & VKLCD70RT)

Committer:
tvendov
Date:
Fri Nov 03 08:52:07 2017 +0000
Revision:
0:0383b9f88d72
Touch panel driver initial release

Who changed what in which revision?

UserRevisionLine numberNew contents of line
tvendov 0:0383b9f88d72 1 #include "Touch.hpp"
tvendov 0:0383b9f88d72 2
tvendov 0:0383b9f88d72 3
tvendov 0:0383b9f88d72 4
tvendov 0:0383b9f88d72 5 namespace Vekatech {
tvendov 0:0383b9f88d72 6
tvendov 0:0383b9f88d72 7 #define DISABLED 0
tvendov 0:0383b9f88d72 8 #define LAST_SAMPLE 1
tvendov 0:0383b9f88d72 9 #define ALL_SAMPLES 2
tvendov 0:0383b9f88d72 10
tvendov 0:0383b9f88d72 11 //Debug is disabled by default
tvendov 0:0383b9f88d72 12 #define TOUCH_DBG DISABLED
tvendov 0:0383b9f88d72 13 //#define MORE_DETAILS
tvendov 0:0383b9f88d72 14
tvendov 0:0383b9f88d72 15 #ifndef FUNCTION_NAME
tvendov 0:0383b9f88d72 16 //#define FUNCTION_NAME ""
tvendov 0:0383b9f88d72 17 //#define FUNCTION_NAME __func__
tvendov 0:0383b9f88d72 18 //#define FUNCTION_NAME __FUNCTION__
tvendov 0:0383b9f88d72 19 #define FUNCTION_NAME __PRETTY_FUNCTION__
tvendov 0:0383b9f88d72 20 #endif
tvendov 0:0383b9f88d72 21
tvendov 0:0383b9f88d72 22 #if (TOUCH_DBG > DISABLED)
tvendov 0:0383b9f88d72 23 #ifdef MORE_DETAILS
tvendov 0:0383b9f88d72 24 #define DBG(x, ...) printf("[DBG: %s:%s:%d] " x "\r\n", __FILE__, FUNCTION_NAME, __LINE__, ##__VA_ARGS__)
tvendov 0:0383b9f88d72 25 #else
tvendov 0:0383b9f88d72 26 #define DBG(x, ...) printf("[DBG:] " x "\r\n", ##__VA_ARGS__)
tvendov 0:0383b9f88d72 27 #endif
tvendov 0:0383b9f88d72 28 #else
tvendov 0:0383b9f88d72 29 #define DBG(x, ...)
tvendov 0:0383b9f88d72 30 #endif
tvendov 0:0383b9f88d72 31
tvendov 0:0383b9f88d72 32 #if (TOUCH_DBG > LAST_SAMPLE)
tvendov 0:0383b9f88d72 33 #ifdef MORE_DETAILS
tvendov 0:0383b9f88d72 34 #define DBG_MORE(x, ...) printf("[DBG_MORE: %s:%s:%d] " x "\r\n", __FILE__, FUNCTION_NAME, __LINE__, ##__VA_ARGS__)
tvendov 0:0383b9f88d72 35 #else
tvendov 0:0383b9f88d72 36 #define DBG_MORE(x, ...) printf("[DBG_MORE:] " x "\r\n", ##__VA_ARGS__)
tvendov 0:0383b9f88d72 37 #endif
tvendov 0:0383b9f88d72 38 #else
tvendov 0:0383b9f88d72 39 #define DBG_MORE(x, ...)
tvendov 0:0383b9f88d72 40 #endif
tvendov 0:0383b9f88d72 41
tvendov 0:0383b9f88d72 42 #if (TOUCH_DBG > ALL_SAMPLES)
tvendov 0:0383b9f88d72 43 #ifdef MORE_DETAILS
tvendov 0:0383b9f88d72 44 #define DBG_ALL(x, ...) printf("[DBG_ALL: %s:%s:%d] " x "\r\n", __FILE__, FUNCTION_NAME, __LINE__, ##__VA_ARGS__)
tvendov 0:0383b9f88d72 45 #else
tvendov 0:0383b9f88d72 46 #define DBG_ALL(x, ...) printf("[DBG_ALL:] " x "\r\n", ##__VA_ARGS__)
tvendov 0:0383b9f88d72 47 #endif
tvendov 0:0383b9f88d72 48 #else
tvendov 0:0383b9f88d72 49 #define DBG_ALL(x, ...)
tvendov 0:0383b9f88d72 50 #endif
tvendov 0:0383b9f88d72 51
tvendov 0:0383b9f88d72 52
tvendov 0:0383b9f88d72 53
tvendov 0:0383b9f88d72 54 #define NEW_TOUCH_DATA 0x1
tvendov 0:0383b9f88d72 55
tvendov 0:0383b9f88d72 56 const touch_config_t STMPE811_cfg = {
tvendov 0:0383b9f88d72 57 "STMPE811", LCD_VDC5_CH0_PANEL, RESISTIVE,
tvendov 0:0383b9f88d72 58 {I_2_C, TPIIC_SDA, TPIIC_SCL, NC, NC, NC, NC, 100000},
tvendov 0:0383b9f88d72 59 {INT_ON_EDGE, FALLING_OR_ACTIVE_LO, TPIRQ_PIN}
tvendov 0:0383b9f88d72 60 };
tvendov 0:0383b9f88d72 61
tvendov 0:0383b9f88d72 62 osThreadId TouchThreadID;
tvendov 0:0383b9f88d72 63
tvendov 0:0383b9f88d72 64 /**************************************************************************//**
tvendov 0:0383b9f88d72 65 * @brief Constructor of the Touch class
tvendov 0:0383b9f88d72 66 * @param[in] pointer to Config structure (touch_config_t)
tvendov 0:0383b9f88d72 67 ******************************************************************************/
tvendov 0:0383b9f88d72 68 //SPI(tp_cfg->interface.mosi, tp_cfg->interface.miso, tp_cfg->interface.sclk, tp_cfg->interface.ssel),
tvendov 0:0383b9f88d72 69 Touch::Touch( const touch_config_t * tp_cfg ) : I2C(tp_cfg->interface.sda, tp_cfg->interface.scl), InterruptIn(tp_cfg->activity_irq.pin)
tvendov 0:0383b9f88d72 70 {
tvendov 0:0383b9f88d72 71 if(tp_cfg == NULL)
tvendov 0:0383b9f88d72 72 touch_cfg = &STMPE811_cfg;
tvendov 0:0383b9f88d72 73 else
tvendov 0:0383b9f88d72 74 touch_cfg = tp_cfg;
tvendov 0:0383b9f88d72 75
tvendov 0:0383b9f88d72 76 x = y = z = 0; adc_x = adc_y = adc_z = 0;
tvendov 0:0383b9f88d72 77 xyz_data = screen_data; adc_data = raw_data;
tvendov 0:0383b9f88d72 78 last_xyz_idx = FIFO_DEPTH-1;
tvendov 0:0383b9f88d72 79
tvendov 0:0383b9f88d72 80 dot_thd = 0;
tvendov 0:0383b9f88d72 81 fraction = 0;
tvendov 0:0383b9f88d72 82 calib.data.flag = 0;
tvendov 0:0383b9f88d72 83 } /* End of constructor */
tvendov 0:0383b9f88d72 84
tvendov 0:0383b9f88d72 85
tvendov 0:0383b9f88d72 86 /**************************************************************************//**
tvendov 0:0383b9f88d72 87 * @brief Destructor of the Touch class
tvendov 0:0383b9f88d72 88 ******************************************************************************/
tvendov 0:0383b9f88d72 89 Touch::~Touch( )
tvendov 0:0383b9f88d72 90 {
tvendov 0:0383b9f88d72 91 Thread::State S = thd.get_state();
tvendov 0:0383b9f88d72 92
tvendov 0:0383b9f88d72 93 disable_irq();
tvendov 0:0383b9f88d72 94
tvendov 0:0383b9f88d72 95 if((S != Thread::Inactive) && (S != Thread::Deleted))
tvendov 0:0383b9f88d72 96 {
tvendov 0:0383b9f88d72 97 thd.terminate();
tvendov 0:0383b9f88d72 98 thd.join();
tvendov 0:0383b9f88d72 99 }
tvendov 0:0383b9f88d72 100
tvendov 0:0383b9f88d72 101 touch_cfg = NULL;
tvendov 0:0383b9f88d72 102 xyz_data = NULL;
tvendov 0:0383b9f88d72 103 adc_data = NULL;
tvendov 0:0383b9f88d72 104 }
tvendov 0:0383b9f88d72 105
tvendov 0:0383b9f88d72 106
tvendov 0:0383b9f88d72 107 /**************************************************************************//**
tvendov 0:0383b9f88d72 108 * @brief Touch controller initialization
tvendov 0:0383b9f88d72 109 * @retval error code
tvendov 0:0383b9f88d72 110 ******************************************************************************/
tvendov 0:0383b9f88d72 111 Touch::init_err_t Touch::Init( void )
tvendov 0:0383b9f88d72 112 {
tvendov 0:0383b9f88d72 113 init_err_t tp_err;
tvendov 0:0383b9f88d72 114
tvendov 0:0383b9f88d72 115 if(touch_cfg->type == RESISTIVE)
tvendov 0:0383b9f88d72 116 {
tvendov 0:0383b9f88d72 117 tp_err = Clb_Setup();
tvendov 0:0383b9f88d72 118
tvendov 0:0383b9f88d72 119 if(tp_err != TOUCH_OK)
tvendov 0:0383b9f88d72 120 return tp_err;
tvendov 0:0383b9f88d72 121 }
tvendov 0:0383b9f88d72 122
tvendov 0:0383b9f88d72 123 if(touch_cfg->interface.type == I_2_C)
tvendov 0:0383b9f88d72 124 I2C::frequency(touch_cfg->interface.freq);
tvendov 0:0383b9f88d72 125 //else
tvendov 0:0383b9f88d72 126 //SPI::frequency(touch_cfg->interface.freq);
tvendov 0:0383b9f88d72 127
tvendov 0:0383b9f88d72 128 tp_err = Drv_Setup();
tvendov 0:0383b9f88d72 129
tvendov 0:0383b9f88d72 130 if(tp_err != TOUCH_OK)
tvendov 0:0383b9f88d72 131 return tp_err;
tvendov 0:0383b9f88d72 132 else
tvendov 0:0383b9f88d72 133 {
tvendov 0:0383b9f88d72 134 thd.start(callback(this, &Touch::Handle_touch));
tvendov 0:0383b9f88d72 135
tvendov 0:0383b9f88d72 136 if(touch_cfg->activity_irq.polarity == FALLING_OR_ACTIVE_LO)
tvendov 0:0383b9f88d72 137 {
tvendov 0:0383b9f88d72 138 rise(NULL);
tvendov 0:0383b9f88d72 139 fall(Irq_Alert);
tvendov 0:0383b9f88d72 140 }
tvendov 0:0383b9f88d72 141 else
tvendov 0:0383b9f88d72 142 {
tvendov 0:0383b9f88d72 143 rise(Irq_Alert);
tvendov 0:0383b9f88d72 144 fall(NULL);
tvendov 0:0383b9f88d72 145 }
tvendov 0:0383b9f88d72 146
tvendov 0:0383b9f88d72 147 enable_irq();
tvendov 0:0383b9f88d72 148 }
tvendov 0:0383b9f88d72 149
tvendov 0:0383b9f88d72 150 return tp_err;
tvendov 0:0383b9f88d72 151 } /* End of method Init() */
tvendov 0:0383b9f88d72 152
tvendov 0:0383b9f88d72 153
tvendov 0:0383b9f88d72 154 /**************************************************************************//**
tvendov 0:0383b9f88d72 155 * @brief Set Calibration data
tvendov 0:0383b9f88d72 156 * @retval error code
tvendov 0:0383b9f88d72 157 ******************************************************************************/
tvendov 0:0383b9f88d72 158 Touch::init_err_t Touch::Clb_Setup()
tvendov 0:0383b9f88d72 159 {
tvendov 0:0383b9f88d72 160 if(touch_cfg->name == "STMPE811")
tvendov 0:0383b9f88d72 161 {
tvendov 0:0383b9f88d72 162 #ifndef __USE_DEFAULT_CALIBRATION_DATA__
tvendov 0:0383b9f88d72 163 // extract calibration info from lcdpanel EEPROM
tvendov 0:0383b9f88d72 164 char adr = 0;
tvendov 0:0383b9f88d72 165
tvendov 0:0383b9f88d72 166 if( (touch_cfg->interface.sda == EEIIC_SDA) || (touch_cfg->interface.scl == EEIIC_SCL))
tvendov 0:0383b9f88d72 167 { // lcdpanel EEPROM is on the same I2C channel no need to initialize a new one !
tvendov 0:0383b9f88d72 168 if(I2C::write(EE_CALIB_DEVICE_ADDR, (const char *)&adr, 1, true) != 0)
tvendov 0:0383b9f88d72 169 return TOUCH_INIT_ERR;
tvendov 0:0383b9f88d72 170 if(I2C::read(EE_CALIB_DEVICE_ADDR, (char*)calib.KX08, sizeof(calib.KX08)) != 0)
tvendov 0:0383b9f88d72 171 return TOUCH_INIT_ERR;
tvendov 0:0383b9f88d72 172 }
tvendov 0:0383b9f88d72 173 else
tvendov 0:0383b9f88d72 174 { // lcdpanel EEPROM is on different I2C channel so initialize a new one !
tvendov 0:0383b9f88d72 175 I2C clb_eeprom(EEIIC_SDA, EEIIC_SCL);
tvendov 0:0383b9f88d72 176
tvendov 0:0383b9f88d72 177 clb_eeprom.frequency(100000);
tvendov 0:0383b9f88d72 178 if(clb_eeprom.write(EE_CALIB_DEVICE_ADDR, (const char *)&adr, 1, true) != 0)
tvendov 0:0383b9f88d72 179 return TOUCH_INIT_ERR;
tvendov 0:0383b9f88d72 180 if(clb_eeprom.read(EE_CALIB_DEVICE_ADDR, (char*)calib.KX08, sizeof(calib.KX08)) != 0)
tvendov 0:0383b9f88d72 181 return TOUCH_INIT_ERR;
tvendov 0:0383b9f88d72 182 }
tvendov 0:0383b9f88d72 183 #endif
tvendov 0:0383b9f88d72 184
tvendov 0:0383b9f88d72 185 if(calib.data.flag != 1)
tvendov 0:0383b9f88d72 186 { // load default calibration info
tvendov 0:0383b9f88d72 187 unsigned char clb[] = {TPCALIBRATION_DATA};
tvendov 0:0383b9f88d72 188 memcpy(calib.KX08, clb, sizeof(clb));
tvendov 0:0383b9f88d72 189 }
tvendov 0:0383b9f88d72 190
tvendov 0:0383b9f88d72 191 return TOUCH_OK;
tvendov 0:0383b9f88d72 192 }
tvendov 0:0383b9f88d72 193 else
tvendov 0:0383b9f88d72 194 return TOUCH_UNSUPP_ERR;
tvendov 0:0383b9f88d72 195 } /* End of method Clb_Setup() */
tvendov 0:0383b9f88d72 196
tvendov 0:0383b9f88d72 197
tvendov 0:0383b9f88d72 198 /**************************************************************************//**
tvendov 0:0383b9f88d72 199 * @brief Set Touch Controller settings
tvendov 0:0383b9f88d72 200 * @retval error code
tvendov 0:0383b9f88d72 201 ******************************************************************************/
tvendov 0:0383b9f88d72 202 Touch::init_err_t Touch::Drv_Setup()
tvendov 0:0383b9f88d72 203 {
tvendov 0:0383b9f88d72 204 if(touch_cfg->name == "STMPE811")
tvendov 0:0383b9f88d72 205 {
tvendov 0:0383b9f88d72 206 unsigned char i, initdata[][2] = { INIT_DATA };
tvendov 0:0383b9f88d72 207
tvendov 0:0383b9f88d72 208 for(i=0; i<(sizeof(initdata)>>1); i++)
tvendov 0:0383b9f88d72 209 {
tvendov 0:0383b9f88d72 210 if(initdata[i][0] == INT_CTRL)
tvendov 0:0383b9f88d72 211 { // reconfigure interrupt if needed
tvendov 0:0383b9f88d72 212 initdata[i][1] = 0x01;
tvendov 0:0383b9f88d72 213 initdata[i][1] |= (touch_cfg->activity_irq.trigger == INT_ON_EDGE)? 0x02 : 0x00;
tvendov 0:0383b9f88d72 214 initdata[i][1] |= (touch_cfg->activity_irq.polarity == RISING_OR_ACTIVE_HI)? 0x04 : 0x00;
tvendov 0:0383b9f88d72 215 }
tvendov 0:0383b9f88d72 216
tvendov 0:0383b9f88d72 217 if(initdata[i][0] == FIFO_TH)
tvendov 0:0383b9f88d72 218 { // save threshold
tvendov 0:0383b9f88d72 219 if(initdata[i][1] < 2)
tvendov 0:0383b9f88d72 220 initdata[i][1] = 2;
tvendov 0:0383b9f88d72 221
tvendov 0:0383b9f88d72 222 dot_thd = initdata[i][1]-1;
tvendov 0:0383b9f88d72 223 }
tvendov 0:0383b9f88d72 224
tvendov 0:0383b9f88d72 225 if(initdata[i][0] == TSC_FRACT_Z)
tvendov 0:0383b9f88d72 226 fraction = initdata[i][1]; // save z precision
tvendov 0:0383b9f88d72 227
tvendov 0:0383b9f88d72 228 if ((I2C::write(STMPE811_DEVICE_ADDR, (const char *)&initdata[i][0], 2)) != 0)
tvendov 0:0383b9f88d72 229 return TOUCH_INIT_ERR;
tvendov 0:0383b9f88d72 230
tvendov 0:0383b9f88d72 231 while (I2C::write(STMPE811_DEVICE_ADDR, (const char *)initdata, 0) != 0); // ACK polling
tvendov 0:0383b9f88d72 232 }
tvendov 0:0383b9f88d72 233
tvendov 0:0383b9f88d72 234 return TOUCH_OK;
tvendov 0:0383b9f88d72 235 }
tvendov 0:0383b9f88d72 236 else
tvendov 0:0383b9f88d72 237 return TOUCH_UNSUPP_ERR;
tvendov 0:0383b9f88d72 238 }
tvendov 0:0383b9f88d72 239
tvendov 0:0383b9f88d72 240
tvendov 0:0383b9f88d72 241 /**************************************************************************//**
tvendov 0:0383b9f88d72 242 * @brief Get Status of the pen
tvendov 0:0383b9f88d72 243 * @retval true : StylusDown
tvendov 0:0383b9f88d72 244 * false : StyluUp
tvendov 0:0383b9f88d72 245 ******************************************************************************/
tvendov 0:0383b9f88d72 246 bool Touch::Get_Pen_Status()
tvendov 0:0383b9f88d72 247 {
tvendov 0:0383b9f88d72 248 if(touch_cfg->name == "STMPE811")
tvendov 0:0383b9f88d72 249 {
tvendov 0:0383b9f88d72 250 unsigned char pen = TSC_CTRL;
tvendov 0:0383b9f88d72 251
tvendov 0:0383b9f88d72 252 I2C::write(STMPE811_DEVICE_ADDR, (const char *)&pen, 1, true);
tvendov 0:0383b9f88d72 253 pen = 0;
tvendov 0:0383b9f88d72 254 I2C::read(STMPE811_DEVICE_ADDR, (char *)&pen, 1);
tvendov 0:0383b9f88d72 255
tvendov 0:0383b9f88d72 256 return (pen & TSC_STA)? true : false;
tvendov 0:0383b9f88d72 257 }
tvendov 0:0383b9f88d72 258 else
tvendov 0:0383b9f88d72 259 return false;
tvendov 0:0383b9f88d72 260 } /* End of method Get_Pen_Status() */
tvendov 0:0383b9f88d72 261
tvendov 0:0383b9f88d72 262
tvendov 0:0383b9f88d72 263 /**************************************************************************//**
tvendov 0:0383b9f88d72 264 * @brief Get one sample of data
tvendov 0:0383b9f88d72 265 * @param[in] * raw : pointer to ring buffer to store the samples
tvendov 0:0383b9f88d72 266 ******************************************************************************/
tvendov 0:0383b9f88d72 267 void Touch::Get_Data( unsigned long long * raw )
tvendov 0:0383b9f88d72 268 {
tvendov 0:0383b9f88d72 269 if(touch_cfg->name == "STMPE811")
tvendov 0:0383b9f88d72 270 {
tvendov 0:0383b9f88d72 271 int idx = last_xyz_idx;
tvendov 0:0383b9f88d72 272 unsigned char i, packed_sample[dot_thd * 4];
tvendov 0:0383b9f88d72 273 unsigned short raw_x, raw_y;
tvendov 0:0383b9f88d72 274 unsigned char raw_z;
tvendov 0:0383b9f88d72 275
tvendov 0:0383b9f88d72 276 i = TSC_DATA_FIFO;
tvendov 0:0383b9f88d72 277 I2C::write(STMPE811_DEVICE_ADDR, (const char *)&i, 1, true);
tvendov 0:0383b9f88d72 278 I2C::read(STMPE811_DEVICE_ADDR, (char *)packed_sample, sizeof(packed_sample));
tvendov 0:0383b9f88d72 279 for(i=0; i<dot_thd; i++)
tvendov 0:0383b9f88d72 280 {
tvendov 0:0383b9f88d72 281 raw_x = (unsigned short)((packed_sample[(i*4)+0]<<4) | (packed_sample[(i*4)+1]>>4));
tvendov 0:0383b9f88d72 282 raw_y = (unsigned short)(((0x0F & packed_sample[(i*4)+1])<<8) | packed_sample[(i*4)+2]);
tvendov 0:0383b9f88d72 283 raw_z = packed_sample[(i*4)+3];
tvendov 0:0383b9f88d72 284
tvendov 0:0383b9f88d72 285 idx = ((idx+1) < FIFO_DEPTH)? idx+1 : 0;
tvendov 0:0383b9f88d72 286 ((touch_raw_data_t*)raw)[idx].axis.x = raw_x;
tvendov 0:0383b9f88d72 287 ((touch_raw_data_t*)raw)[idx].axis.y = raw_y;
tvendov 0:0383b9f88d72 288 ((touch_raw_data_t*)raw)[idx].axis.z = raw_z;
tvendov 0:0383b9f88d72 289 }
tvendov 0:0383b9f88d72 290 }
tvendov 0:0383b9f88d72 291 } /* End of method Get_Data() */
tvendov 0:0383b9f88d72 292
tvendov 0:0383b9f88d72 293
tvendov 0:0383b9f88d72 294 /**************************************************************************//**
tvendov 0:0383b9f88d72 295 * @brief Get all available samples of data
tvendov 0:0383b9f88d72 296 * @param[in] * raw : pointer to ring buffer to store the samples
tvendov 0:0383b9f88d72 297 * @retval samples count
tvendov 0:0383b9f88d72 298 ******************************************************************************/
tvendov 0:0383b9f88d72 299 int Touch::Get_Fifo( unsigned long long * raw )
tvendov 0:0383b9f88d72 300 {
tvendov 0:0383b9f88d72 301 if(touch_cfg->name == "STMPE811")
tvendov 0:0383b9f88d72 302 {
tvendov 0:0383b9f88d72 303 int idx = last_xyz_idx;
tvendov 0:0383b9f88d72 304 unsigned char packets;
tvendov 0:0383b9f88d72 305
tvendov 0:0383b9f88d72 306 packets = FIFO_SIZE;
tvendov 0:0383b9f88d72 307 I2C::write(STMPE811_DEVICE_ADDR, (const char *)&packets, 1, true);
tvendov 0:0383b9f88d72 308 packets = 0;
tvendov 0:0383b9f88d72 309 I2C::read(STMPE811_DEVICE_ADDR, (char *)&packets, 1);
tvendov 0:0383b9f88d72 310 if(packets)
tvendov 0:0383b9f88d72 311 {
tvendov 0:0383b9f88d72 312 unsigned char packed_sample[packets * 4];
tvendov 0:0383b9f88d72 313 unsigned short raw_x, raw_y, i;
tvendov 0:0383b9f88d72 314 unsigned char raw_z;
tvendov 0:0383b9f88d72 315
tvendov 0:0383b9f88d72 316 raw_z = TSC_DATA_FIFO;
tvendov 0:0383b9f88d72 317 I2C::write(STMPE811_DEVICE_ADDR, (const char *)&raw_z, 1, true);
tvendov 0:0383b9f88d72 318 I2C::read(STMPE811_DEVICE_ADDR, (char *)packed_sample, packets*4);
tvendov 0:0383b9f88d72 319
tvendov 0:0383b9f88d72 320 for(i=0; i<packets; i++)
tvendov 0:0383b9f88d72 321 {
tvendov 0:0383b9f88d72 322 raw_x = (unsigned short)((packed_sample[(i*4)+0]<<4) | (packed_sample[(i*4)+1]>>4));
tvendov 0:0383b9f88d72 323 raw_y = (unsigned short)(((0x0F & packed_sample[(i*4)+1])<<8) | packed_sample[(i*4)+2]);
tvendov 0:0383b9f88d72 324 raw_z = packed_sample[(i*4)+3];
tvendov 0:0383b9f88d72 325
tvendov 0:0383b9f88d72 326 idx = ((idx+1) < FIFO_DEPTH)? idx+1 : 0;
tvendov 0:0383b9f88d72 327 ((touch_raw_data_t*)raw)[idx].axis.x = raw_x;
tvendov 0:0383b9f88d72 328 ((touch_raw_data_t*)raw)[idx].axis.y = raw_y;
tvendov 0:0383b9f88d72 329 ((touch_raw_data_t*)raw)[idx].axis.z = raw_z;
tvendov 0:0383b9f88d72 330 }
tvendov 0:0383b9f88d72 331
tvendov 0:0383b9f88d72 332 return packets;
tvendov 0:0383b9f88d72 333 }
tvendov 0:0383b9f88d72 334 return 0;
tvendov 0:0383b9f88d72 335 }
tvendov 0:0383b9f88d72 336 else
tvendov 0:0383b9f88d72 337 return 0;
tvendov 0:0383b9f88d72 338 } /* End of method Get_Fifo() */
tvendov 0:0383b9f88d72 339
tvendov 0:0383b9f88d72 340
tvendov 0:0383b9f88d72 341 /**************************************************************************//**
tvendov 0:0383b9f88d72 342 * @brief Coordinates Transfer function
tvendov 0:0383b9f88d72 343 * @param[in] points : number of samples which have to become meaningful
tvendov 0:0383b9f88d72 344 ******************************************************************************/
tvendov 0:0383b9f88d72 345 void Touch::Get_XYZ( int points)
tvendov 0:0383b9f88d72 346 {
tvendov 0:0383b9f88d72 347 if(touch_cfg->name == "STMPE811")
tvendov 0:0383b9f88d72 348 {
tvendov 0:0383b9f88d72 349 int i, idx;
tvendov 0:0383b9f88d72 350
tvendov 0:0383b9f88d72 351 for(i=0; i<points; i++)
tvendov 0:0383b9f88d72 352 {
tvendov 0:0383b9f88d72 353 idx = ((last_xyz_idx+1) < FIFO_DEPTH)? last_xyz_idx+1 : 0;
tvendov 0:0383b9f88d72 354 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);
tvendov 0:0383b9f88d72 355 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);
tvendov 0:0383b9f88d72 356 screen_data[idx].axis.z = ((float)(raw_data[idx].axis.z >> fraction)) + (((float)(raw_data[idx].axis.z & ((0x1<<fraction)-1)))*(1.0f/float(0x1<<fraction)));
tvendov 0:0383b9f88d72 357 last_xyz_idx = idx;
tvendov 0:0383b9f88d72 358 #ifdef MORE_DETAILS
tvendov 0:0383b9f88d72 359 DBG_MORE("TH_No: (%d) X-> %d (%d), Y-> %d (%d), Z-> %f (%d), dots-> %d/%d", idx, screen_data[idx].axis.x, raw_data[idx].axis.x, screen_data[idx].axis.y, raw_data[idx].axis.y, screen_data[idx].axis.z, raw_data[idx].axis.z, i+1, points);
tvendov 0:0383b9f88d72 360 #else
tvendov 0:0383b9f88d72 361 DBG_MORE("TH_No: (%d) X-> %d, Y-> %d, Z-> %f, dots-> %d/%d", idx, screen_data[idx].axis.x, screen_data[idx].axis.y, screen_data[idx].axis.z, i+1, points);
tvendov 0:0383b9f88d72 362 #endif
tvendov 0:0383b9f88d72 363 }
tvendov 0:0383b9f88d72 364
tvendov 0:0383b9f88d72 365 x = screen_data[last_xyz_idx].axis.x; adc_x = raw_data[last_xyz_idx].axis.x;
tvendov 0:0383b9f88d72 366 y = screen_data[last_xyz_idx].axis.y; adc_y = raw_data[last_xyz_idx].axis.y;
tvendov 0:0383b9f88d72 367 z = screen_data[last_xyz_idx].axis.z; adc_z = raw_data[last_xyz_idx].axis.z;
tvendov 0:0383b9f88d72 368 #ifdef MORE_DETAILS
tvendov 0:0383b9f88d72 369 DBG("S_No: (%d) X-> %d (%d), Y-> %d (%d), Z-> %f (%d), dots-> %d", last_xyz_idx, x, adc_x, y, adc_y, z, adc_z, points);
tvendov 0:0383b9f88d72 370 #else
tvendov 0:0383b9f88d72 371 DBG("S_No: (%d) X-> %d, Y-> %d, Z-> %f, dots-> %d", last_xyz_idx, x, y, z, points);
tvendov 0:0383b9f88d72 372 #endif
tvendov 0:0383b9f88d72 373 }
tvendov 0:0383b9f88d72 374 } /* End of method Get_XYZ() */
tvendov 0:0383b9f88d72 375
tvendov 0:0383b9f88d72 376
tvendov 0:0383b9f88d72 377 /**************************************************************************//**
tvendov 0:0383b9f88d72 378 * @brief IRQ interrupt handler : indicates "New Touch Data available" which activates i2c data transfer in Handle_touch()
tvendov 0:0383b9f88d72 379 ******************************************************************************/
tvendov 0:0383b9f88d72 380 void Touch::Irq_Alert()
tvendov 0:0383b9f88d72 381 {
tvendov 0:0383b9f88d72 382 // Execute the time critical part first
tvendov 0:0383b9f88d72 383
tvendov 0:0383b9f88d72 384 // Then the rest can execute later in user context (and can contain code that's not interrupt safe).
tvendov 0:0383b9f88d72 385 osSignalSet(TouchThreadID, NEW_TOUCH_DATA);
tvendov 0:0383b9f88d72 386 }
tvendov 0:0383b9f88d72 387
tvendov 0:0383b9f88d72 388
tvendov 0:0383b9f88d72 389 /**************************************************************************//**
tvendov 0:0383b9f88d72 390 * @brief Get index of the last sample in the ring buffer
tvendov 0:0383b9f88d72 391 * @retval idx
tvendov 0:0383b9f88d72 392 ******************************************************************************/
tvendov 0:0383b9f88d72 393 int Touch::Get_Last_Idx() { return last_xyz_idx; }
tvendov 0:0383b9f88d72 394
tvendov 0:0383b9f88d72 395 /**************************************************************************//**
tvendov 0:0383b9f88d72 396 * @brief Get dot collection threshold
tvendov 0:0383b9f88d72 397 * @retval threshold
tvendov 0:0383b9f88d72 398 ******************************************************************************/
tvendov 0:0383b9f88d72 399 int Touch::Get_Dot_thd() { return dot_thd; }
tvendov 0:0383b9f88d72 400
tvendov 0:0383b9f88d72 401 /**************************************************************************//**
tvendov 0:0383b9f88d72 402 * @brief Pull the new samples if new touch data is available
tvendov 0:0383b9f88d72 403 ******************************************************************************/
tvendov 0:0383b9f88d72 404 void Touch::Handle_touch()
tvendov 0:0383b9f88d72 405 {
tvendov 0:0383b9f88d72 406 bool Stylus = false;
tvendov 0:0383b9f88d72 407 bool Click_send = false;
tvendov 0:0383b9f88d72 408 unsigned short idx_on = 0;
tvendov 0:0383b9f88d72 409 unsigned char TP_IntStat = 0, rec[2];
tvendov 0:0383b9f88d72 410 int dots = 0;
tvendov 0:0383b9f88d72 411 osEvent evt;
tvendov 0:0383b9f88d72 412
tvendov 0:0383b9f88d72 413 TouchThreadID = thd.gettid();
tvendov 0:0383b9f88d72 414
tvendov 0:0383b9f88d72 415 while (true)
tvendov 0:0383b9f88d72 416 {
tvendov 0:0383b9f88d72 417 evt = thd.signal_wait(NEW_TOUCH_DATA);
tvendov 0:0383b9f88d72 418
tvendov 0:0383b9f88d72 419 if(evt.status == osEventSignal)
tvendov 0:0383b9f88d72 420 {
tvendov 0:0383b9f88d72 421 if(touch_cfg->name == "STMPE811")
tvendov 0:0383b9f88d72 422 {
tvendov 0:0383b9f88d72 423 TP_IntStat = INT_STA;
tvendov 0:0383b9f88d72 424 I2C::write(STMPE811_DEVICE_ADDR, (const char *)&TP_IntStat, 1, true);
tvendov 0:0383b9f88d72 425 TP_IntStat = 0;
tvendov 0:0383b9f88d72 426 I2C::read(STMPE811_DEVICE_ADDR, (char *)&TP_IntStat, 1);
tvendov 0:0383b9f88d72 427
tvendov 0:0383b9f88d72 428 if(TP_IntStat & INT_FIFO_TH)
tvendov 0:0383b9f88d72 429 {
tvendov 0:0383b9f88d72 430 Get_Data(&raw_data[0].dot);
tvendov 0:0383b9f88d72 431 Get_XYZ(dot_thd);
tvendov 0:0383b9f88d72 432 if(Stylus)
tvendov 0:0383b9f88d72 433 {
tvendov 0:0383b9f88d72 434 if(!Click_send)
tvendov 0:0383b9f88d72 435 {
tvendov 0:0383b9f88d72 436 MSG(EV_STYLUS_DOWN, idx_on, 0);
tvendov 0:0383b9f88d72 437 Click_send = true;
tvendov 0:0383b9f88d72 438 }
tvendov 0:0383b9f88d72 439 MSG(EV_STYLUS_HOLD, idx_on, last_xyz_idx);
tvendov 0:0383b9f88d72 440 }
tvendov 0:0383b9f88d72 441 }
tvendov 0:0383b9f88d72 442
tvendov 0:0383b9f88d72 443 if(TP_IntStat & INT_TOUCH_DET)
tvendov 0:0383b9f88d72 444 {
tvendov 0:0383b9f88d72 445 Stylus = Get_Pen_Status();
tvendov 0:0383b9f88d72 446 DBG("Pen: %s", (Stylus)? "DOWN" : "UP");
tvendov 0:0383b9f88d72 447
tvendov 0:0383b9f88d72 448 dots = Get_Fifo(&raw_data[0].dot);
tvendov 0:0383b9f88d72 449 if(dots)
tvendov 0:0383b9f88d72 450 {
tvendov 0:0383b9f88d72 451 Get_XYZ(dots);
tvendov 0:0383b9f88d72 452
tvendov 0:0383b9f88d72 453 if(Stylus)
tvendov 0:0383b9f88d72 454 {
tvendov 0:0383b9f88d72 455 int on = (last_xyz_idx+1) - dots;
tvendov 0:0383b9f88d72 456 idx_on = (on<0)? (FIFO_DEPTH-on) : on;
tvendov 0:0383b9f88d72 457 MSG(EV_STYLUS_DOWN, idx_on, 0);
tvendov 0:0383b9f88d72 458 Click_send = true;
tvendov 0:0383b9f88d72 459 }
tvendov 0:0383b9f88d72 460 else
tvendov 0:0383b9f88d72 461 {
tvendov 0:0383b9f88d72 462 if(!Click_send)
tvendov 0:0383b9f88d72 463 {
tvendov 0:0383b9f88d72 464 MSG(EV_STYLUS_DOWN, idx_on, 0);
tvendov 0:0383b9f88d72 465 Click_send = true;
tvendov 0:0383b9f88d72 466 }
tvendov 0:0383b9f88d72 467 MSG(EV_STYLUS_UP, idx_on, last_xyz_idx);
tvendov 0:0383b9f88d72 468 }
tvendov 0:0383b9f88d72 469 }
tvendov 0:0383b9f88d72 470 else
tvendov 0:0383b9f88d72 471 {
tvendov 0:0383b9f88d72 472 if(Stylus)
tvendov 0:0383b9f88d72 473 {
tvendov 0:0383b9f88d72 474 Click_send = false;
tvendov 0:0383b9f88d72 475 idx_on = (last_xyz_idx == (FIFO_DEPTH-1))? 0 : last_xyz_idx+1;
tvendov 0:0383b9f88d72 476 }
tvendov 0:0383b9f88d72 477 else
tvendov 0:0383b9f88d72 478 {
tvendov 0:0383b9f88d72 479 if(Click_send)
tvendov 0:0383b9f88d72 480 MSG( EV_STYLUS_UP, idx_on, last_xyz_idx);
tvendov 0:0383b9f88d72 481 }
tvendov 0:0383b9f88d72 482 }
tvendov 0:0383b9f88d72 483 }
tvendov 0:0383b9f88d72 484
tvendov 0:0383b9f88d72 485 if(TP_IntStat & INT_FIFO_OFLOW)
tvendov 0:0383b9f88d72 486 {
tvendov 0:0383b9f88d72 487 DBG("Overflow !!!");
tvendov 0:0383b9f88d72 488
tvendov 0:0383b9f88d72 489 rec[0] = FIFO_STA;
tvendov 0:0383b9f88d72 490 rec[1] = 0x01; // Clear FIFO
tvendov 0:0383b9f88d72 491 I2C::write(STMPE811_DEVICE_ADDR, (const char *)rec, 2);
tvendov 0:0383b9f88d72 492
tvendov 0:0383b9f88d72 493 rec[1] = 0x00; // Reset FIFO
tvendov 0:0383b9f88d72 494 I2C::write(STMPE811_DEVICE_ADDR, (const char *)rec, 2);
tvendov 0:0383b9f88d72 495 }
tvendov 0:0383b9f88d72 496
tvendov 0:0383b9f88d72 497 rec[0] = INT_STA;
tvendov 0:0383b9f88d72 498 rec[1] = TP_IntStat;
tvendov 0:0383b9f88d72 499 I2C::write(STMPE811_DEVICE_ADDR, (const char *)rec, 2);
tvendov 0:0383b9f88d72 500 }
tvendov 0:0383b9f88d72 501 }
tvendov 0:0383b9f88d72 502 else
tvendov 0:0383b9f88d72 503 {
tvendov 0:0383b9f88d72 504 DBG("Abnormal Touch Thread Status: 0x%X", evt.status);
tvendov 0:0383b9f88d72 505 }
tvendov 0:0383b9f88d72 506 }
tvendov 0:0383b9f88d72 507 }
tvendov 0:0383b9f88d72 508
tvendov 0:0383b9f88d72 509 } // namespace Vekatech
tvendov 0:0383b9f88d72 510
tvendov 0:0383b9f88d72 511 /* End of file */