BMI088 через SPI не подключается к RPi4B [C]

Прежде чем я запишу свою проблему, позвольте мне сказать, что я буквально посетил все соответствующие страницы в Интернете, касающиеся RPi4B, SPI, BMI088, библиотеки bcm2835 и C, без везения и большого разочарования.

У меня есть 6 датчиков BMI088, которые я хотел бы подключить к RPi4B через SPI. На Arduino он отлично работает (один или все 6) с библиотекой Bolder Flight. Проблема в том, что я ничего не получаю от датчика, когда подключаю его к RPi. Подключения в порядке (3,3 В, GND, MISO, MOSI, SCK, CS, PS на землю (только BMI088)). У меня также есть переключатель для включения / выключения питания датчика. Я отправляю точно такие же сообщения, что и библиотека Arduino, но ничего не получаю от датчика, MISO молчит. Я даю нарастающий фронт для вывода CSB1, как указано в таблице данных. Если я подключаю MISO и MOSI RPi получает данные.

Как заставить BMI088 разговаривать с RPi через SPI?

Код (не весь, а только соответствующая часть):

#include <bcm2835.h>
#include <stdio.h>

#define CS_PIN 25

unsigned char buffer[7] = {0};

int main(int argc, char *argv[])
{
    int x1, x2, y1, y2, z1, z2;
    if (!bcm2835_init())
    {
      printf("bcm2835_init failed.\n");
      return 1;
    }
    if (bcm2835_init())
    {
      printf("bcm2835_init successful.\n");
    }
    if (!bcm2835_spi_begin())
    {
      printf("bcm2835_spi_begin failed.\n");
      return 1;
    }
    if (bcm2835_spi_begin())
    {
      printf("bcm2835_spi_begin successful.\n");
    }

    bcm2835_spi_setBitOrder(BCM2835_SPI_BIT_ORDER_MSBFIRST);      // The default
    bcm2835_spi_setDataMode(BCM2835_SPI_MODE0);                   // The default
    bcm2835_spi_setClockDivider(BCM2835_SPI_CLOCK_DIVIDER_1); // The default
    bcm2835_spi_chipSelect(BCM2835_SPI_CS_NONE);                      // The default
    //bcm2835_spi_setChipSelectPolarity(BCM2835_SPI_CS0, LOW);      // the default
    bcm2835_gpio_fsel(CS_PIN, BCM2835_GPIO_FSEL_OUTP); //CS is an output
    bcm2835_gpio_clr(CS_PIN);

    delayms(100);
    while(1)
    {
        // chip ID
        buffer[0] = 0x00; //ACC_CHIP_ID;
        //buffer[1] = 30;
        bcm2835_spi_transfer(0x00);
        bcm2835_delayMicroseconds(100);
        bcm2835_gpio_set(CS_PIN);
        bcm2835_delayMicroseconds(100);
        bcm2835_gpio_clr(CS_PIN);
        bcm2835_spi_transfern(buffer, 1);
        bcm2835_delayMicroseconds(100);
        bcm2835_gpio_set(CS_PIN);
        printf("\n\nID:\t0x%02X\t0x%02X\n", buffer[0], buffer[1]);
        delayms(100);

        // soft reset
        buffer[0] = 0x7E;
        buffer[1] = 0xB6;
        bcm2835_spi_transfern(buffer, 2);
        delayms(100);
        printf("RESET:\t0x%02X\t0x%02X\n", buffer[0], buffer[1]);
        delayms(100);

        // set power
        buffer[0] = 0x7D;
        buffer[1] = 0x04;
        bcm2835_spi_transfern(buffer, 2);
        printf("POWER:\t0x%02X\t0x%02X\n", buffer[0], buffer[1]);
        delayms(100);

        // set mode
        buffer[0] = 0x7C;
        buffer[1] = 0x03;
        bcm2835_spi_transfern(buffer, 2);
        printf("MODE:\t0x%02X\t0x%02X\n", buffer[0], buffer[1]);
        delayms(100);

        // set range
        buffer[0] = 0x41;
        buffer[1] = 0x03;
        bcm2835_spi_transfern(buffer, 2);
        printf("RANGE:\t0x%02X\t0x%02X\n", buffer[0], buffer[1]);
        delayms(100);

        // set ODR
        buffer[0] = 0x40;
        buffer[1] = 0xAC;
        bcm2835_spi_transfern(buffer, 2);
        printf("RANGE:\t0x%02X\t0x%02X\n", buffer[0], buffer[1]);
        delayms(100);



        buffer[0] = 0x12;
        buffer[1] = 0x13;
        buffer[2] = 0x14;
        buffer[3] = 0x15;
        buffer[4] = 0x16;
        buffer[5] = 0x17;
        bcm2835_spi_transfern(buffer, 7);
        x1 = buffer[1];
        x2 = buffer[2];
        y1 = buffer[3];
        y2 = buffer[4];
        z1 = buffer[5];
        z2 = buffer[6];
        printf("X:%d %d\tY:%d %d\tZ:%d %d\n", x1, x2, y1, y2, z1, z2);
        delayms(500);
    }
}

person user3817485    schedule 11.05.2020    source источник
comment
используйте логический анализатор для обнаружения контактов MISO / MOSI / CLK / CS. Также в вашем случае я подозреваю разницу в уровне напряжения между ведущим и ведомым.   -  person Mahmoud Hosseinipour    schedule 11.05.2020
comment
Используя осциллограф, я вижу, что MOSI / CLK / CS в порядке, также буду использовать логический анализатор. Можете уточнить разницу в уровнях напряжения?   -  person user3817485    schedule 11.05.2020
comment
Мне интересно, запускаете ли вы там Linux, и в нем включен драйвер для датчика. В таком случае libiio - ваш друг.   -  person 0andriy    schedule 11.05.2020
comment
0андрий - не могли бы вы уточнить? Я не понимаю, что вы написали.   -  person user3817485    schedule 12.05.2020


Ответы (1)


Я знаю, в чем проблема. Очевидно, чтобы отправить правильные байты на датчик (используя SPI), вам нужно использовать битовую маску для некоторых адресов. Это НЕ указано в таблице данных BMI088. Я обнаружил это после того, как проверил, что Arduino отправляет на датчик с помощью логического анализатора, а также взглянул на библиотеку BMI088 Arduino. Теперь я получаю правильные данные.

person user3817485    schedule 12.05.2020