2
votes

Before I write down my problem let me say that I have literally visited all relevant pages on internet regarding RPi4B, SPI, BMI088, bcm2835 library and C, with no luck and a lot of frustration.

I have 6 BMI088 sensors I'd like to connect to RPi4B over SPI. On Arduino it works perfectly (one or all 6) with Bolder Flight library. The problem is I don't get anything from sensor when I connect it to RPi. Connections are ok (3.3 V, GND, MISO, MOSI, SCK, CS, PS to ground (only BMI088)). I also have a switch to turn sensor power ON/OFF. I am sending exactly the same messages as Arduino library does, but I get nothing from the sensor, MISO is silent. I provide a rising edge to CSB1 pin as stated in datasheet. If I connect MISO and MOSI RPi receives data.

How do I get BMI088 to talk to RPi over SPI?

The code (not whole, just relevant part):

#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);
    }
}
1
use logic analyzer to snif MISO/MOSI/CLK/CS pins.Also in your case I suspect to voltage level differences between Master and Slave. - Mahmoud Hosseinipour
Using oscilloscope I see that MOSI/CLK/CS are OK, will use logic analyzer also. Can you clarify voltage level difference? - user3817485
I'm wondering if you run there Linux and it has enabled driver for the sensor. In such case libiio is your friend. - 0andriy
0andriy - could you be more specific? I don't understand what you wrote. - user3817485

1 Answers

1
votes

I know where was the problem. Apparently in order to send correct bytes to the sensor (using SPI) you have to use bit mask for some addresses. This is NOT specified in the BMI088 datasheet. I found that out after I checked what Arduino is sending to the sensor with the logic analyzer and I also took a look at BMI088 Arduino library. Now I get the correct data.