Bosch Sensortec Community

    cancel
    Showing results for 
    Search instead for 
    Did you mean: 

    BMI270 load init using I2C

    New Poster

    BMI270 load init using I2C

    I'm not able to successfully load init data into BMI270 chip using the code below. Since maximum bytes is 255, I load 32 bytes at the time. I get 0x02 as a result from reading 0x21 (status). I do not have any available SPI ports.

    These are the first register readouts:

    24200010000000000000000000000000000000000000000026960101000000000002adff00008000800
    242000100000000000000000000000000000000000000000fcc40100000000000002310000008000800
    242000100000000000000000000000000000000000000000c7f30100000000000002310000008000800
    242000100000000000000000000000000000000000000000a222020000000000000200800000800080
    2420001000000000000000000000000000000000000000007551020000000000000200800000800080

    Any obvious errors? Greatful for any hints or trixes.

    uint16_t i;
    uint16_t j;
    uint32_t err_code;
    uint8_t d[33];
    uint32_t addr;

    nrf_delay_us(500);
    bmi270_write(BMI2_PWR_CONF_ADDR, 0x00); // Power on
    nrf_delay_us(500);

    bmi270_write(BMI2_CMD_REG_ADDR, 0xb6); // Reset
    nrf_delay_ms(500);

    bmi270_write(BMI2_INIT_CTRL_ADDR, 0x00); // init start
    nrf_delay_us(500);

    for(i = 0; i < 256; i++)
    {
    bmi270_write(BMI2_INIT_ADDR_0, 0);
    bmi270_write(BMI2_INIT_ADDR_1, i);

    d[0] = BMI2_INIT_DATA_ADDR;
    addr = i << 5;
    for(j = 0; j < 32; j++)
    {
    d[j+1] = bmi270_config_file[addr + j];
    }

    err_code = nrf_drv_twi_tx(&m_twi, BMI2_I2C_PRIM_ADDR, d, 33, false);
    nrf_delay_us(500);
    }

    nrf_delay_ms(500);
    bmi270_write(BMI2_INIT_CTRL_ADDR, 0x01);
    nrf_delay_ms(500);

    bmi270_write(BMI2_PWR_CONF_ADDR, 0x00); // Power on
    nrf_delay_us(500);
    bmi270_write(BMI2_PWR_CTRL_ADDR, 0x0e); // Accelerometer and gyroscope on
    nrf_delay_us(500);
    bmi270_write(BMI2_FIFO_CONFIG_1_ADDR, 0x00); // FIFO off
    nrf_delay_us(500);

    bmi270_write(BMI2_PWR_CTRL_ADDR, 0x0e); // Accelerometer and gyroscope on
    bmi270_write(BMI2_ACC_CONF_ADDR, 0xbb); // Performance, Avg32, 100Hz
    bmi270_write(BMI2_ACC_RANGE_ADDR,0x00); // Range +- 2g
    bmi270_write(BMI2_GYR_CONF_ADDR, 0xcb); // Performance, normal operation, 200Hz
    bmi270_write(BMI2_GYR_RANGE_ADDR, 0x04); // Gyre range +- 125dps
    bmi270_write(BMI2_FIFO_DOWNS_ADDR, 0x00); // Filtering off
    bmi270_write(BMI2_FIFO_CONFIG_1_ADDR, 0xd0); // Store acc and Gyro in FIFO

    3 REPLIES 3
    Member

    Re: BMI270 load init using I2C

    I'm also having such problem. Please solve this asap!

    Member

    Re: BMI270 load init using I2C

    It seems like I've managed to make it work. These are the necessary steps:

    Implement the i2c write function. I used pigpio library which has exactly what we need: i2cWriteI2CBlockData. I've seen this function in many libraries - it's pretty common. 

    int8_t i2c_reg_write(uint8_t i2c_addr, uint8_t reg_addr, const uint8_t *reg_data, uint16_t length) {

    /* Write to registers using I2C. Return 0 for a successful execution. */

    //int i2cWriteI2CBlockData(unsigned handle, unsigned i2cReg, char *buf, unsigned count)
    int ret = i2cWriteI2CBlockData(i2cHnd, reg_addr, (char *) reg_data, length);
    if (ret != 0) {
    printf("*** ERROR in i2c_reg_write %d\n", ret); // do your error handing thing here
    return 1;
    }
    return 0;
    }

     

    Implement the i2c read function. I stopped experimenting with the details of read function immediately when this produced good results. Possibly the i2cReadI2CBlockData would work... But instead of that this one just increments the register address  and the position in the resulting buffer. Important to undestand that with this approach you won't be able to read back the freshly written config data. That has to be done through the BMI2_INIT_DATA_ADDR register in combination with BMI2_INIT_ADDR_0 and BMI2_INIT_ADDR_1. tldr, this one works.

    int8_t i2c_reg_read(uint8_t i2c_addr, uint8_t reg_addr, uint8_t *reg_data, uint16_t length) {

    /* Read from registers using I2C. Return 0 for a successful execution. */
    uint16_t count = 0;
    int res;
    while (count < length) {
    res = i2cReadByteData(i2cHnd, (reg_addr + count));
    if (res < 0) {
    printf("*** ERROR in i2c_reg_read %d\n", res);
    return 1;
    }
    reg_data[count] = (uint8_t)(res & 0xff);
    count++;
    }
    return 0;
    }

    EDIT: My first tests validate that i2cReadI2CBlockData can be used also. 

    int8_t i2c_reg_read(uint8_t i2c_addr, uint8_t reg_addr, uint8_t *reg_data, uint16_t length) {
    int
    ret = i2cReadI2CBlockData(i2cHnd, reg_addr, (char *)reg_data, length);
    return (ret > 0) ? 0 : 1; // all good
    }

     

    Then implement the delay_us( uint32_t period )  function. I used the nanosleep from #include <time.h>. The delay_us function's period - after converting it - ends up here. 

    long secs, nanoSec;
    struct
    timespec req, rem;
    req.tv_sec = secs;
    req.tv_nsec = nanoSec;
    while (nanosleep(&req, &rem));

     

    Right before the good old bmi270_init is called the device gets configured. Here we need to change the maximum size of the chunk we are able to send.  Change  read_write_len = 128  to M where M is the maximum number of bytes your I2C lib is able to send using i2cWriteI2CBlockData. In my case it's 32.

    dev.delay_us = delay_us;
    dev.read_write_len = 32; // ***** THIS must be changed according to the used I2C lib ***
    dev.intf = BMI2_I2C_INTERFACE;

     

    Last but not least you must open the proper I2C bus where the sensor is. Which usually involves some GPIO initialization. So in my case it is:

    init_gpio();

    i2c_open();

    ... call here the function which creates the device and calls bmi270_init(&device), etc ...

    ... the sensor works, you can have a cookie. ...

    i2c_close();

    terminate_gpio();

    This will produce good config result in address: BMI2_INTERNAL_STATUS_ADDR. Go for the message bits (3..0) particularly value 1 which is message: "init_ok".

     

     

    Contributor

    Re: BMI270 load init using I2C

    Thanks crmabs for the detailed tutorial !
    Icon--AD-black-48x48Icon--address-consumer-data-black-48x48Icon--appointment-black-48x48Icon--back-left-black-48x48Icon--calendar-black-48x48Icon--center-alignedIcon--Checkbox-checkIcon--clock-black-48x48Icon--close-black-48x48Icon--compare-black-48x48Icon--confirmation-black-48x48Icon--dealer-details-black-48x48Icon--delete-black-48x48Icon--delivery-black-48x48Icon--down-black-48x48Icon--download-black-48x48Ic-OverlayAlertIcon--externallink-black-48x48Icon-Filledforward-right_adjustedIcon--grid-view-black-48x48IC_gd_Check-Circle170821_Icons_Community170823_Bosch_Icons170823_Bosch_Icons170821_Icons_CommunityIC-logout170821_Icons_Community170825_Bosch_Icons170821_Icons_CommunityIC-shopping-cart2170821_Icons_CommunityIC-upIC_UserIcon--imageIcon--info-i-black-48x48Icon--left-alignedIcon--Less-minimize-black-48x48Icon-FilledIcon--List-Check-grennIcon--List-Check-blackIcon--List-Cross-blackIcon--list-view-mobile-black-48x48Icon--list-view-black-48x48Icon--More-Maximize-black-48x48Icon--my-product-black-48x48Icon--newsletter-black-48x48Icon--payment-black-48x48Icon--print-black-48x48Icon--promotion-black-48x48Icon--registration-black-48x48Icon--Reset-black-48x48Icon--right-alignedshare-circle1Icon--share-black-48x48Icon--shopping-bag-black-48x48Icon-shopping-cartIcon--start-play-black-48x48Icon--store-locator-black-48x48Ic-OverlayAlertIcon--summary-black-48x48tumblrIcon-FilledvineIc-OverlayAlertwhishlist