Использование драйвера I2C Dev - PullRequest
0 голосов
/ 31 мая 2018

Я хочу настроить датчик по шине 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 Ответ

0 голосов
/ 01 июня 2018

Я не знаю интерфейс к вашему чипу.Существует множество возможных способов использования 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-инструменты, которые смогут делать то, что вы хотите.

...