Hello everyone:
New to the community. Running into an interesting behavior with BMI270, wondering if any one has an answer there.
Using BMI270, able to read the CHIP-ID correctly. After soft-reset and wait for 1000ms, reading the value of registers, PWR_CONF and PWR_CTRL, both comes back as 0x00, while it is supporsed to be 0x03 for PWR_CONF. Intersting is if read PWR_CTRL first then read PWR_CONF, it comes back as0x03 and 0x00. Any idea why?
Attaching some source code here for reference.
void device_imu_bmi270_reset()
{
uint8_t value = 0xFF;
mcu_spi_io_pkg bmi270_spi_io_pkg;
bmi270_spi_io_pkg.bytesToSendReceive = 2;
bmi270_spi_io_pkg.p_tx_buffer = tx_buffer;
bmi270_spi_io_pkg.p_rx_buffer = rx_buffer;
bmi270_spi_io_pkg.devnum = MCU_SPI_DEV_BMI270;
tx_buffer[0] = BMI270_COMMAND_WRITE | BMI270_REG_CMD;
tx_buffer[1] = BMI270_COMMAND_RESET;
mcu_spi_io(&bmi270_spi_io_pkg);
printLog("BMI270 resetting\r\n");
sl_sleeptimer_delay_millisecond(1000);
//device_imu_bmi270_read_register_onebyte(BMI270_REG_PWRCONF); //0x03
device_imu_bmi270_read_register_onebyte(BMI270_REG_PWRCTRL); //0x00
device_imu_bmi270_read_register_onebyte(BMI270_REG_PWRCONF); //0x03
//simply switch these two above lines, the output gets correct
}
The read function is defined as
uint8_t device_imu_bmi270_read_register_onebyte(uint8_t addr)
{
mcu_spi_io_pkg bmi270_spi_io_pkg;
bmi270_spi_io_pkg.bytesToSendReceive = 3;
bmi270_spi_io_pkg.p_tx_buffer = tx_buffer;
bmi270_spi_io_pkg.p_rx_buffer = rx_buffer;
bmi270_spi_io_pkg.devnum = MCU_SPI_DEV_BMI270;
tx_buffer[0] = BMI270_COMMAND_READ | addr;
tx_buffer[1] = BMI270_DUMMY_DATA; // 16 bit protocol. dummy byte needed before read actual data
tx_buffer[2] = BMI270_DUMMY_DATA; // dummy
mcu_spi_io(&bmi270_spi_io_pkg); // send data to BMI270
printLog("Read byte is 0x%02x\r\n",rx_buffer[2]);
return rx_buffer[2];
}
Thanks for your inputs
Solved! Go to Solution.
After the soft reset the BMI270 will be back in I2C mode and you'll have to get it to switch back to SPI mode before attempting to read the registers. I ususlly just toggle the CS low for 10ms but you can also perform a "dummy" register read to get it to switch. I also add a small delay after switching before reading the first register to give it time to switch but this isn't documented in the datasheet so I don't know if it's required (but probably a good idea).