andrewm@0: /*
andrewm@0:  * I2c_TouchKey.cpp
andrewm@0:  *
andrewm@0:  *  Created on: Oct 14, 2013
andrewm@0:  *      Author: Victor Zappi
andrewm@0:  */
andrewm@0: 
andrewm@0: 
andrewm@0: 
andrewm@0: #include "I2c_TouchKey.h"
andrewm@0: 
andrewm@0: #undef DEBUG_I2C_TOUCHKEY
andrewm@0: 
andrewm@0: I2c_TouchKey::I2c_TouchKey()
andrewm@0: {
andrewm@0: 	isReady = false;
andrewm@15: 	sensorType = kSensorTypeTouchKey;
andrewm@0: 	touchCount = 0;
andrewm@0: 	sliderSize[0] = sliderSize[1] = sliderSize[2] = -1;
andrewm@0: 	sliderPosition[0] = sliderPosition[1] = sliderPosition[2] = -1;
andrewm@0: 	sliderPositionH = -1;
andrewm@0: }
andrewm@0: 
andrewm@15: int I2c_TouchKey::initTouchKey(int sensorTypeToUse)
andrewm@0: {
andrewm@15: 	sensorType = sensorTypeToUse;
andrewm@15: 	if(sensorType > 2 || sensorType < 0)
andrewm@15: 		sensorType = 2;
andrewm@15: 
andrewm@15: 	numBytesToRead = kSensorBytes[sensorType];
andrewm@0: 
andrewm@0: 	char buf[3] = { 0x00, 0x01, 0x00 }; // code for centroid mode
andrewm@0: 	if(write(i2C_file, buf, 3) !=3)
andrewm@0: 	{
andrewm@0: 		cout << "Failed to set TouchKey in \"Centroid Mode\" " << endl;
andrewm@0: 		return 1;
andrewm@0: 	}
andrewm@0: 
andrewm@0: 	usleep(5000); // need to give TouchKey enough time to process command
andrewm@0: 
andrewm@0: 	char buf4[4] = { 0x00, 0x07, 0x00, 0x64}; // code for change minimum touch area
andrewm@0: 	if(write(i2C_file, buf4, 4) !=4)
andrewm@0: 	{
andrewm@0: 		cout << "Failed to set TouchKey minimum touch size" << endl;
andrewm@0: 		return 1;
andrewm@0: 	}
andrewm@0: 
andrewm@0: 	usleep(5000); // need to give TouchKey enough time to process command
andrewm@0: 
andrewm@15: 	if(sensorType == kSensorTypeDBox2)
andrewm@15: 		buf[0] = 0x04; // code for data collection
andrewm@15: 	else
andrewm@15: 		buf[0] = 0x06; // code for data collection
andrewm@15: 
andrewm@0: 	if(write(i2C_file, buf, 1) !=1)
andrewm@0: 	{
andrewm@0: 		cout << "Failed to prepare data collection " << endl;
andrewm@0: 		return 2;
andrewm@0: 	}
andrewm@0: 
andrewm@0: 	usleep(5000); // need to give TouchKey enough time to process command
andrewm@0: 
andrewm@0: 	isReady = true;
andrewm@0: 
andrewm@0: 	return 0;
andrewm@0: }
andrewm@0: 
andrewm@0: 
andrewm@0: int I2c_TouchKey::readI2C()
andrewm@0: {
andrewm@0: 	bytesRead = read(i2C_file, dataBuffer, numBytesToRead);
andrewm@0: 	if (bytesRead != numBytesToRead)
andrewm@0: 	{
andrewm@0: 		cout << "Failure to read Byte Stream" << endl;
andrewm@0: 		return 2;
andrewm@0: 	}
andrewm@0: 	/*cout << NUM_BYTES << " bytes read" << endl;
andrewm@0: 	for(int j=0; j<9; j++)
andrewm@0: 		cout << "\t" << (int)dataBuffer[j];
andrewm@0: 	cout << endl;
andrewm@0: 	*/
andrewm@0: 
andrewm@0: 	touchCount = 0;
andrewm@0: 
andrewm@0: 	// Old TouchKeys sensors have 3 touch locations plus horizontal positions
andrewm@0: 	// New D-Box sensors have 5 touch locations but no horizontal position
andrewm@15: 	// Later D-Box sensors have same data in a different format
andrewm@15: 	if(sensorType == kSensorTypeDBox1) {
andrewm@15: 		rawSliderPosition[0] = (((dataBuffer[0] & 0xF0) << 4) + dataBuffer[1]);
andrewm@15: 		rawSliderPosition[1] = (((dataBuffer[0] & 0x0F) << 8) + dataBuffer[2]);
andrewm@15: 		rawSliderPosition[2] = (((dataBuffer[3] & 0xF0) << 4) + dataBuffer[4]);
andrewm@0: 		rawSliderPosition[3] = (((dataBuffer[5] & 0xF0) << 4) + dataBuffer[6]);
andrewm@0: 		rawSliderPosition[4] = (((dataBuffer[5] & 0x0F) << 8) + dataBuffer[7]);
andrewm@0: 		rawSliderPositionH = 0x0FFF;
andrewm@0: 	}
andrewm@15: 	else if(sensorType == kSensorTypeDBox2) {
andrewm@15: 		rawSliderPosition[0] = ((dataBuffer[0] << 8) + dataBuffer[1]) & 0x0FFF;
andrewm@15: 		rawSliderPosition[1] = ((dataBuffer[2] << 8) + dataBuffer[3]) & 0x0FFF;
andrewm@15: 		rawSliderPosition[2] = ((dataBuffer[4] << 8) + dataBuffer[5]) & 0x0FFF;
andrewm@15: 		rawSliderPosition[3] = ((dataBuffer[6] << 8) + dataBuffer[7]) & 0x0FFF;
andrewm@15: 		rawSliderPosition[4] = ((dataBuffer[8] << 8) + dataBuffer[9]) & 0x0FFF;
andrewm@15: 		rawSliderPositionH = 0x0FFF;
andrewm@15: 	}
andrewm@15: 	else {
andrewm@15: 		rawSliderPosition[0] = (((dataBuffer[0] & 0xF0) << 4) + dataBuffer[1]);
andrewm@15: 		rawSliderPosition[1] = (((dataBuffer[0] & 0x0F) << 8) + dataBuffer[2]);
andrewm@15: 		rawSliderPosition[2] = (((dataBuffer[3] & 0xF0) << 4) + dataBuffer[4]);
andrewm@0: 		rawSliderPosition[3] = 0x0FFF;
andrewm@0: 		rawSliderPosition[4] = 0x0FFF;
andrewm@0: 		rawSliderPositionH   = (((dataBuffer[3] & 0x0F) << 8) + dataBuffer[5]);
andrewm@0: 	}
andrewm@0: 
andrewm@0: 	for(int i = 0; i < 5; i++)
andrewm@0: 	{
andrewm@0: 		if(rawSliderPosition[i] != 0x0FFF) // 0x0FFF means no touch
andrewm@0: 		{
andrewm@15: 			if(sensorType != kSensorTypeTouchKey)
andrewm@0: 				sliderPosition[i] = (float)rawSliderPosition[i] / 3200.0;   // New sensors; 26 pads (128 * 25)
andrewm@0: 			else
andrewm@0: 				sliderPosition[i] = (float)rawSliderPosition[i] / 2432.0;	// White keys, vertical (128 * 19)
andrewm@15: 
andrewm@15: 			if(sliderPosition[i] > 1.0)
andrewm@0: 				sliderPosition[i] = 1.0;
andrewm@15: 
andrewm@15: 			if(sensorType == kSensorTypeDBox2) {
andrewm@15: 				sliderSize[i]     = (float)((dataBuffer[2*i + 10] << 8) + dataBuffer[2*i + 11]) / 5000.0;
andrewm@15: 				if(sliderSize[i] > 1.0)
andrewm@15: 					sliderSize[i] = 1.0;
andrewm@15: 			}
andrewm@15: 			else if(sensorType == kSensorTypeDBox1)
andrewm@0: 				sliderSize[i]     = (float)dataBuffer[i + 8] / 255.0;
andrewm@0: 			else {
andrewm@0: 				if(i < 3)
andrewm@0: 					sliderSize[i]     = (float)dataBuffer[i + 6] / 255.0;
andrewm@0: 				else
andrewm@0: 					sliderSize[i]     = 0.0;
andrewm@0: 			}
andrewm@0: 			touchCount++;
andrewm@0: 		}
andrewm@0: 		else {
andrewm@0: 			sliderPosition[i] = -1.0;
andrewm@0: 			sliderSize[i]     = 0.0;
andrewm@0: 		}
andrewm@0: 	}
andrewm@0: 
andrewm@0: 
andrewm@0: 
andrewm@0: 	if(rawSliderPositionH != 0x0FFF)
andrewm@0: 	{
andrewm@0: 		sliderPositionH = (float)rawSliderPositionH / 256.0;			// White keys, horizontal (1 byte + 1 bit)
andrewm@0: 	}
andrewm@0: 	else
andrewm@0: 		sliderPositionH = -1.0;
andrewm@0: 
andrewm@0: #ifdef DEBUG_I2C_TOUCHKEY
andrewm@0: 	for(int i = 0; i < bytesRead; i++) {
andrewm@0: 		printf("%2X ", dataBuffer[i]);
andrewm@0: 	}
andrewm@0: 	cout << touchCount << " touches: ";
andrewm@0: 	for(int i = 0; i < touchCount; i++) {
andrewm@0: 		cout << "(" << sliderPosition[i] << ", " << sliderSize[i] << ") ";
andrewm@0: 	}
andrewm@0: 	cout << "H = " << sliderPositionH << endl;
andrewm@0: #endif
andrewm@0: 
andrewm@0: 	return 0;
andrewm@0: }
andrewm@0: 
andrewm@0: 
andrewm@0: I2c_TouchKey::~I2c_TouchKey()
andrewm@0: {}
andrewm@0: