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".
... View more