you need to first set some settings and then set the offset so you can read back data. I have used the code below:
uint8_t identifyBuf[] = {kOffsetCommand, kCommandIdentify};
int ret = HAL_I2C_Master_Transmit(&trillHi2c, gI2cAddress, identifyBuf, sizeof(identifyBuf), kTimeout);
if(HAL_OK != ret) {
fprintf(stderr, "Error: send identify command\n\r");
return 1;
}
HAL_Delay(10);
uint8_t receiveBuffer[4];
ret = HAL_I2C_Master_Receive(&trillHi2c, gI2cAddress, receiveBuffer, sizeof(receiveBuffer), kTimeout);
if(HAL_OK != ret) {
fprintf(stderr, "Error: receive identify command\n\r");
return 1;
}
printf("identify: %#4x %#4x %#4x %#4x\n\r", receiveBuffer[0], receiveBuffer[1], receiveBuffer[2], receiveBuffer[3]);
HAL_Delay(10);
uint8_t diffBuf[] = {kOffsetCommand, kCommandMode, kModeCentroid};
ret = HAL_I2C_Master_Transmit(&trillHi2c, gI2cAddress, diffBuf, sizeof(diffBuf), kTimeout);
if(HAL_OK != ret) {
fprintf(stderr, "Error: send mode command\n\r");
return 1;
}
// update baseline
uint8_t updateBaselineBuffer[] = {kOffsetCommand, kCommandBaselineUpdate};
ret = HAL_I2C_Master_Transmit(&trillHi2c, gI2cAddress, updateBaselineBuffer, sizeof(updateBaselineBuffer), kTimeout);
if(HAL_OK != ret) {
fprintf(stderr, "Error: send update baseline command\n\r");
return 1;
}
// prepare to read data
uint8_t transmitBuffer[] = {kOffsetData};
ret = HAL_I2C_Master_Transmit(&trillHi2c, gI2cAddress, transmitBuffer, sizeof(transmitBuffer), kTimeout);
if(HAL_OK != ret) {
fprintf(stderr, "Error: prepare to read command\n\r");
return 1;
}
// now read data
while(1) {
uint8_t receiveBuffer[kNumTouches * 2 * 2];
ret = HAL_I2C_Master_Receive(&trillHi2c, gI2cAddress, receiveBuffer, sizeof(receiveBuffer), kTimeout);
if(HAL_OK != ret) {
fprintf(stderr, "Error: blocking receive\n\r");
return 1;
}
for(unsigned int n = 0; n < kNumTouches; ++n)
{
uint16_t location = ((receiveBuffer[2 * n] << 8) + receiveBuffer[2 * n + 1]);
uint16_t size = ((receiveBuffer[2 * n + kNumTouches * 2] << 8) + receiveBuffer[2 * n + 1 + kNumTouches * 2]);
if(location != 0xffff)
{
if(0 == n)
{
firstLocation = location;
firstSize = size;
}
printf("[%d] %d %d, ", n, location, size);
}
}
}
However, if you have a floating point unit , a memory allocator and a few spare CPU cycles, you could use the Trill library for Linux as it is, using this I2c.h
file:
#pragma once
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include "main.h"
typedef unsigned char i2c_char_t;
class I2c
{
protected:
int i2C_address;
ssize_t readBytes(void* buf, size_t count);
ssize_t writeBytes(const void* buf, size_t count);
enum { kTimeout = 10 };
I2C_HandleTypeDef* hi2c;
public:
I2c(){};
I2c(I2c&&) = delete;
int initI2C_RW(int bus, int address, int file = -1);
virtual int readI2C() = 0;
int closeI2C();
virtual ~I2c();
};
inline int I2c::initI2C_RW(int bus, int address, int fileHnd)
{
extern I2C_HandleTypeDef hi2c2;
hi2c = &hi2c2;
i2C_address = address << 1;
return 0;
}
inline int I2c::closeI2C()
{
return 0;
}
inline ssize_t I2c::readBytes(void *buf, size_t count)
{
HAL_StatusTypeDef ret = HAL_I2C_Master_Receive(hi2c, i2C_address, (uint8_t*)buf, count, kTimeout);
if(HAL_OK == ret)
return count;
else
return -1;
}
inline ssize_t I2c::writeBytes(const void *buf, size_t count)
{
HAL_StatusTypeDef ret = HAL_I2C_Master_Transmit(hi2c, i2C_address, (uint8_t*)buf, count, kTimeout);
if(HAL_OK == ret)
return count;
else
return -1;
}
inline I2c::~I2c(){}
inline int usleep(useconds_t us)
{
HAL_Delay((us + 999) / 1000);
return 0;
}
, and calling tril.newData()
from within the HAL_I2C_MasterRxCpltCallback()
if you are using DMA, or from within a loop where you call HAL_I2C_Master_Receive()
.