Использование драйвера I2C dev
Я хочу настроить датчик по шине I2C с помощью модуля I2C-dev. Необходимая шина I2C запущена и работает, однако я не могу получить никаких данных от датчика. Может ли кто-нибудь помочь мне отладить приведенный ниже код. Все регистры датчиков являются 8-битными.
int main()
{
int devFile=0;
const char *devFileName="/dev/i2c-1";
char writeBuf[2];
uint16_t readBuf[2];
uint16_t tempReading = 0;
/* Initialize I2C interface */
devFile = hdc2010_i2c_init(devFileName, HDC2010_ADDR);
/* Configuring the sensor and trigerring measurement */
writeBuf[0] = HDC2010_CONFIG;
writeBuf[1] = 0x57;
hdc2010_i2c_write(devFile, writeBuf, 2);
writeBuf[0] = HDC2010_INTERRUPT_CONFIG;
writeBuf[1] = 0x78;
hdc2010_i2c_write(devFile, writeBuf, 2);
writeBuf[0] = HDC2010_MEASUREMENT_CONFIG;
writeBuf[1] = 0x03;
hdc2010_i2c_write(devFile, writeBuf, 2);
/* Reading temperature data from the registers */
writeBuf[0] = HDC2010_TEMP_LOW;
hdc2010_i2c_write(devFile, writeBuf, 1);
readBuf[0] = hdc2010_i2c_read(devFile, 1);
writeBuf[0] = HDC2010_TEMP_HIGH;
hdc2010_i2c_write(devFile, writeBuf, 1);
readBuf[1] = hdc2010_i2c_read(devFile, 1);
/*
* Converting the temperature to readable format
* Formula Source : HDC2010 Datasheet
*/
tempReading = ((readBuf[1] << 8) | (readBuf[0]));
tempReading = ((tempReading/65536)*165)-40;
printf("\nTemp: %d\n",tempReading);
}
int hdc2010_i2c_init(const char *devFileName, int slaveAddr)
{
int devFile;
/* Opening I2C device file */
devFile=open(devFileName,O_RDWR);
if (devFile < 0)
{
printf("\nError opening the %s device file.\n",devFileName);
exit (1);
}
/* Selecting HDC2010 by its slave address */
if (ioctl(devFile,I2C_SLAVE,slaveAddr) < 0)
{
printf("\nFailed to select HDC2010(addr=%u)\n",HDC2010_ADDR);
exit (1);
}
return devFile;
}
void hdc2010_i2c_write(int devFile, char *buf, int numBytes)
{
write(devFile, buf, numBytes);
}
uint16_t hdc2010_i2c_read(int devFile, int numBytes)
{
uint16_t readBuf;
read(devFile, &readBuf, 1);
return readBuf;
}
Нужно ли использовать команды SMBus или достаточно чтения / записи? Есть ли тестовые приложения, как в случае с SPIdev?
1 ответ
Я не знаю интерфейс к вашему чипу. Существует множество возможных способов использования I2C. Но есть очень распространенный способ доступа к устройству с 8-битными регистрами, поэтому давайте предположим, что это то, что вам нужно.
Чтобы прочитать регистр, вы хотите сгенерировать (упрощенную) примитивную последовательность I2C:
Start I2CAddr+Write RegAddr Start I2CAddr+Read [DATA] Stop
Но то, что вы делаете, это:
Start I2CAddr+Write RegAddr Stop
Start I2CAddr+Read [DATA] Stop
По сути, вам нужно, чтобы операция чтения регистра была единственной транзакцией с одной остановкой в конце и повторным запуском между режимом записи и режимом чтения. Но вы отправляете две транзакции.
Вы не должны использовать read()
/write()
интерфейс для i2c-dev. Этот интерфейс очень прост и не подходит для большинства транзакций I2C. Вместо этого используйте ioctl()
интерфейс и I2C_RDWR
, Это позволяет генерировать соответствующие транзакции.
Поскольку некоторые формы транзакций очень распространены, в том числе те, которые вам, скорее всего, нужны, есть библиотека, в которой они уже закодированы. использование i2c_smbus_read_byte_data()
а также i2c_smbus_write_byte_data()
из библиотеки в i2c-tools.
Что касается тестовых программ, то здесь есть i2cget
а также i2cset
, часть вышеупомянутых i2c-инструментов, которые смогут делать то, что вы хотите.