view projects/d-box/I2c_TouchKey.cpp @ 12:a6beeba3a648

Initial support for higher matrix sample rates by reducing the number of channels. Input not tested yet, and not all examples updated to new format.
author andrewm
date Thu, 22 Jan 2015 19:00:22 +0000
parents 8a575ba3ab52
children 901d205d1a3c
line wrap: on
line source
/*
 * I2c_TouchKey.cpp
 *
 *  Created on: Oct 14, 2013
 *      Author: Victor Zappi
 */



#include "I2c_TouchKey.h"

#undef DEBUG_I2C_TOUCHKEY

I2c_TouchKey::I2c_TouchKey()
{
	isReady = false;
	newSensor = false;
	touchCount = 0;
	sliderSize[0] = sliderSize[1] = sliderSize[2] = -1;
	sliderPosition[0] = sliderPosition[1] = sliderPosition[2] = -1;
	sliderPositionH = -1;
}

int I2c_TouchKey::initTouchKey(bool useNewSensor)
{
	newSensor = useNewSensor;
	numBytesToRead = newSensor ? NUM_BYTES_NEW : NUM_BYTES_OLD;

	char buf[3] = { 0x00, 0x01, 0x00 }; // code for centroid mode
	if(write(i2C_file, buf, 3) !=3)
	{
		cout << "Failed to set TouchKey in \"Centroid Mode\" " << endl;
		return 1;
	}

	usleep(5000); // need to give TouchKey enough time to process command

	char buf4[4] = { 0x00, 0x07, 0x00, 0x64}; // code for change minimum touch area
	if(write(i2C_file, buf4, 4) !=4)
	{
		cout << "Failed to set TouchKey minimum touch size" << endl;
		return 1;
	}

	usleep(5000); // need to give TouchKey enough time to process command

	buf[0] = 0x06; // code for data collection
	if(write(i2C_file, buf, 1) !=1)
	{
		cout << "Failed to prepare data collection " << endl;
		return 2;
	}

	usleep(5000); // need to give TouchKey enough time to process command

	isReady = true;

	return 0;
}


int I2c_TouchKey::readI2C()
{
	bytesRead = read(i2C_file, dataBuffer, numBytesToRead);
	if (bytesRead != numBytesToRead)
	{
		cout << "Failure to read Byte Stream" << endl;
		return 2;
	}
	/*cout << NUM_BYTES << " bytes read" << endl;
	for(int j=0; j<9; j++)
		cout << "\t" << (int)dataBuffer[j];
	cout << endl;
	*/

	touchCount = 0;

	rawSliderPosition[0] = (((dataBuffer[0] & 0xF0) << 4) + dataBuffer[1]);
	rawSliderPosition[1] = (((dataBuffer[0] & 0x0F) << 8) + dataBuffer[2]);
	rawSliderPosition[2] = (((dataBuffer[3] & 0xF0) << 4) + dataBuffer[4]);

	// Old TouchKeys sensors have 3 touch locations plus horizontal positions
	// New D-Box sensors have 5 touch locations but no horizontal position
	if(newSensor)
	{
		rawSliderPosition[3] = (((dataBuffer[5] & 0xF0) << 4) + dataBuffer[6]);
		rawSliderPosition[4] = (((dataBuffer[5] & 0x0F) << 8) + dataBuffer[7]);
		rawSliderPositionH = 0x0FFF;
	}
	else
	{
		rawSliderPosition[3] = 0x0FFF;
		rawSliderPosition[4] = 0x0FFF;
		rawSliderPositionH   = (((dataBuffer[3] & 0x0F) << 8) + dataBuffer[5]);
	}


	for(int i = 0; i < 5; i++)
	{
		if(rawSliderPosition[i] != 0x0FFF) // 0x0FFF means no touch
		{
			//sliderPosition[i] = (float)rawSliderPosition[i] / 1536.0;	// Black keys, vertical (128 * 12)
			//sliderPosition[i] = (float)rawSliderPosition[i] / 768.0;	// Cute white key, for simple instrument
			if(newSensor)
				sliderPosition[i] = (float)rawSliderPosition[i] / 3200.0;   // New sensors; 26 pads (128 * 25)
			else
				sliderPosition[i] = (float)rawSliderPosition[i] / 2432.0;	// White keys, vertical (128 * 19)
			if(sliderPosition[i]>1.0)
				sliderPosition[i] = 1.0;
			if(newSensor)
				sliderSize[i]     = (float)dataBuffer[i + 8] / 255.0;
			else {
				if(i < 3)
					sliderSize[i]     = (float)dataBuffer[i + 6] / 255.0;
				else
					sliderSize[i]     = 0.0;
			}
			touchCount++;
		}
		else {
			sliderPosition[i] = -1.0;
			sliderSize[i]     = 0.0;
		}
	}



	if(rawSliderPositionH != 0x0FFF)
	{
		sliderPositionH = (float)rawSliderPositionH / 256.0;			// White keys, horizontal (1 byte + 1 bit)
	}
	else
		sliderPositionH = -1.0;

#ifdef DEBUG_I2C_TOUCHKEY
	for(int i = 0; i < bytesRead; i++) {
		printf("%2X ", dataBuffer[i]);
	}
	cout << touchCount << " touches: ";
	for(int i = 0; i < touchCount; i++) {
		cout << "(" << sliderPosition[i] << ", " << sliderSize[i] << ") ";
	}
	cout << "H = " << sliderPositionH << endl;
#endif

	return 0;
}


I2c_TouchKey::~I2c_TouchKey()
{}