Чтение барометра Ettus E310 через I2C, всегда возвращает отсутствие такого устройства или адреса (-1) - PullRequest
0 голосов
/ 07 февраля 2019

Я пытался написать драйвер устройства I2C для барометра BMP 180 и датчика температуры, найденных на E310 (как видно на листе 9 схемы .) Iя основывал свой код на примере драйвера, заданного bosch .

Драйверу требуются указатели функций для блокировки чтения и записи, а также спящего режима, которые в основном являются единственным исходным кодом:

int8_t user_i2c_read(uint8_t dev_id, uint8_t reg_addr,uint8_t *data, uint16_t len)   
int8_t user_i2c_write(uint8_t dev_id, uint8_t reg_addr,uint8_t *data, uint16_t len)
void user_delay_ms(uint32_t period)

Проблема, с которой я сталкиваюсь, заключается в том, что этот драйвер (а также более простые программы SMBUS только для написанных мной программ) всегда не могли прочитать или записать адрес i2c 0x77, где датчик должен быть расположен на шине.

readBytes для идентификатора устройства 0x77: -1 - Нет такого устройства или адреса

Несмотря на то, что мой код, кажется, работает для местоположений, в которых расположены другие устройства (хотя я не сделал ничего, кроме проверки связи с ними)

ДвижениеДатчик:

readBytes для идентификатора устройства 0x69: 0 - успех

Датчик температуры:

readBytes для идентификатора устройства 0x19: 0 - успех

Мне было интересно, что не так с моим кодом, что устройство не отвечает, или какая аппаратная конфигурация отсутствует, что объясняет отсутствие связи с ней.Электронный барометр в 0x77.

Я заметил, что барометр BMP-180 установлен на вспомогательном i2c гироскопа MPU-9150 , но из-за проводки и таблицы данных я думаю, что он находится в режиме сквозного прохождения, а не в главном.Режим.Просто мысль, которая у меня была.

Вот весь мой код, который взаимодействует с bmpDriver .

Скомпилирован со следующим

gcc test.c -o test -std = c11 -D _DEFAULT_SOURCE

#include "bmp280.c"
#include <linux/i2c-dev-user.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>

int8_t user_i2c_read(uint8_t dev_id, uint8_t reg_addr,uint8_t *data, uint16_t len){
    int file;
    file = open("/dev/i2c-0", O_RDWR);
    if(file < 0)
    {
        printf("Failed to open /dev/i2c-0\n");
        close(file);
        return -1;
    }
    if(ioctl(file, I2C_SLAVE, dev_id) < 0)
    {
        printf("ioctl failed for /dev/i2c-0 at %x - %s\n", dev_id, strerror(errno));
        close(file);
        return -2;
    }
    int readBytes;
    readBytes = i2c_smbus_read_block_data(file, reg_addr, data);
    printf("readBytes for device ID 0x%x: %d - %s\n", dev_id, readBytes, strerror(errno));
    close(file);
    return readBytes;
}

int8_t user_i2c_write(uint8_t dev_id, uint8_t reg_addr,uint8_t *data, uint16_t len){
    int file;
    file = open("/dev/i2c-0", O_RDWR);
    if(file < 0)
    {
        printf("Failed to open /dev/i2c-0\n");
        close(file);
        return -1;
    }
    if(ioctl(file, I2C_SLAVE, dev_id) < 0)
    {
        printf("ioctl failed for /dev/i2c-0 at %x - %s\n", dev_id, strerror(errno));
        close(file);
        return -2;
    }
    int writeBytes;
    uint8_t shortLen = len;
    writeBytes = i2c_smbus_write_block_data(file, reg_addr, shortLen, data);
    printf("writeBytes for device ID 0x%x: %d - %s\n", dev_id, writeBytes, strerror(errno));
    close(file);
    return writeBytes;
}

void user_delay_ms(uint32_t period){
    unsigned int sleep = period;
    usleep(sleep * 1000);
}

int main(){
    int8_t rslt;
    struct bmp280_dev user_bmp;
    user_bmp.dev_id = BMP280_I2C_ADDR_SEC;
    user_bmp.intf = BMP280_I2C_INTF;
    user_bmp.read = user_i2c_read;
    user_bmp.write = user_i2c_write;
    user_bmp.delay_ms = user_delay_ms;
    rslt = bmp280_init(&user_bmp);
    if (rslt == BMP280_OK) {
      printf("Device found with chip id 0x%x\n", user_bmp.chip_id);
    }
    else {
      printf("Device not found, exiting...\n");
      return -1;
    }
    struct bmp280_config conf;
    rslt = bmp280_get_config(&conf, &user_bmp);
    conf.filter = BMP280_FILTER_COEFF_2;
    conf.os_pres = BMP280_OS_16X;
    conf.os_temp = BMP280_OS_4X;
    conf.odr = BMP280_ODR_1000_MS;
    rslt = bmp280_set_config(&conf, &user_bmp);
    rslt = bmp280_set_power_mode(BMP280_NORMAL_MODE, &user_bmp);
    struct bmp280_uncomp_data ucomp_data;
    uint8_t meas_dur = bmp280_compute_meas_time(&user_bmp);
    printf("Measurement duration: %dms\r\n", meas_dur);
    uint8_t i;
    for (i = 0; (i < 10) && (rslt == BMP280_OK); i++) {
        printf("Running measurement: %d\n", i+1);
        user_bmp.delay_ms(meas_dur); 
        rslt = bmp280_get_uncomp_data(&ucomp_data, &user_bmp);
        int32_t temp32 = bmp280_comp_temp_32bit(ucomp_data.uncomp_temp, &user_bmp);
        uint32_t pres32 = bmp280_comp_pres_32bit(ucomp_data.uncomp_press, &user_bmp);
        uint32_t pres64 = bmp280_comp_pres_64bit(ucomp_data.uncomp_press, &user_bmp);
        double temp = bmp280_comp_temp_double(ucomp_data.uncomp_temp, &user_bmp);
        double pres = bmp280_comp_pres_double(ucomp_data.uncomp_press, &user_bmp);
        printf("UT: %d, UP: %d, T32: %d, P32: %d, P64: %d, P64N: %d, T: %f, P: %f\r\n", \
          ucomp_data.uncomp_temp, ucomp_data.uncomp_press, temp32, \
          pres32, pres64, pres64 / 256, temp, pres);
        user_bmp.delay_ms(1000);
    }
    if(rslt != BMP280_OK){
        printf("Result not okay at measurement: %d\n", i);
    }
}

1 Ответ

0 голосов
/ 10 февраля 2019

Прежде чем начать с предположения, я бы удостоверился, что передача действительно достигает датчика за гироскопом.Просто используйте любую область для измерения SCL и SDA.Если устройство получает передачу, показание области действия предоставит дополнительную информацию о том, где устройство NAK.

Одно различие между BMP и другими устройствами i2c, к которым вы смогли обратиться, которое вызывало у меня многочисленные головные боли в прошлом: BMP, по-видимому, требует повторного запуска условия между адресом устройства и считыванием регистра.

Насколько я помню, стандартные библиотеки i2c не поддерживают это, и вам обычно приходится создавать свои собственные функции чтения / записи с использованием linux / i2c-dev.h.

...