08-25-2021 04:10 PM
Hello,
I've been using the BMI270, which has worked perfectly except for an issue with initialization after the device has been powered off and on.
The device I'm working on uses a Teensy 3.2 to communicate with the BMI270 and some other components through the SPI bus. The device has to be able to go into sleep mode and then wake up and continue sampling the IMU.
When the device is first turned on (battery is connected), the BMI270 is initialized and I've checked that it works correctly. After this I power off the BMI270 using a high-side switch connected to the Teensy and then put the Teensy into sleep using the snooze library. Now when the device wakes up again and I resupply power to the BMI270 it doesn't work anymore (shows all 0's). It says in the datasheet that the init function should be run after each POR or soft reset, so I tried doing that, but I get an initialization error each time (rslt doesn't show BMI2_OK). I've also tried running a soft reset before the init function, but this also gives me an error.
If I don't power off the BMI270 during device sleep it works just fine after wakeup. I've checked with a high precision multimeter and the BMI270 powers off and on as it should (at least there's no current running through it during sleep and there is about 0.8 mA after). Other components like the SD-reader work as expected after I power them off and on again, so the problem shouldn't be with SPI.
I'm not sure why the BMI270 is acting differently after I power it off and on with a high side switch compared to when I disconnect the battery completely.
The full code is quite long and I'm not able to share all of it, but I'm using an API given to me by a moderator here. Main functions I'm using are bmi270_init, bmi2_accel_gyro_set_config, bmi2_soft_reset etc. Please let me know if there are any particular code snippets I can post that can help resolve the issue.
Any help is much appreciated.
Sincerely
Paraas
08-25-2021 05:50 PM
Hi,
Thanks for your inquiry.
On page 26 of BMI270 datasheet, you need to make CSB, SDX, SCX digital IO pins low before you switch off BMI270 VDD and VDDIO as shown below. After you power on BMI270 VDD and VDDIO again, you can bring those pins high. Then BMI270 will get a proper POR and be ready to go with the init function.
Thanks.
08-26-2021 11:18 AM
Thanks for the quick reply!
Great, will give it a try, but I'll have to wait for the changes to be implemented in the hardware. Will post results as soon as it's done 🙂
Sincerely
Paraas
08-30-2021 11:38 AM
Hello,
So I've tried bringing the pins low before power off and high after power on, but I still can't get it to initialize correctly.
I've extracted the relevant parts in the code below.
#####################################################################################################
digitalWrite(BMI270_CS, LOW); //Connected to CSB
digitalWrite(11, LOW); //Connected to SDX
digitalWrite(13, LOW); //Connected to SCX
delay(200);
digitalWrite(IMUpin, HIGH); //Turn off IMU high side switch
wakeupSource = Snooze.deepSleep( button_config ); //Put uController to sleep
digitalWrite(IMUpin, LOW); // Turn on IMU high side switch
digitalWrite(11, HIGH);
digitalWrite(13, HIGH);
SPI.begin();
delay(500);
/* Configure SPI pins to be used by IMU */
digitalWrite(BMI270_CS, HIGH);
SPI.setMOSI(11);
SPI.setMISO(12);
SPI.setSCK(13);
initResult = imuInit(); // Init the IMU
int8_t imuInit() {
/* Variable to define result */
int8_t rslt;
/* Define sensor types in the data struct */
sensor_data[0].type = BMI2_ACCEL;
sensor_data[1].type = BMI2_GYRO;
/* Initialize the read, write, and delay functions for the bmi2 struct */
spi_bus = BMI270_CS;
bmi2.intf_ptr = &spi_bus;
bmi2.intf = BMI2_SPI_INTF;
bmi2.read = BMI270_read_spi;
bmi2.write = BMI270_write_spi;
bmi2.read_write_len = 32;
bmi2.delay_us = bmi2xy_hal_delay_usec;
/* Config file pointer should be assigned to NULL, so that default file address
is assigned in bmi270_init */
bmi2.config_file_ptr = NULL;
int8_t chip_id;
/* Initialize bmi270 */
rslt = bmi270_init(&bmi2);
/* Return 0 on error */
if (rslt != BMI2_OK) return 0;
/* Set sensor configurations */
rslt = bmi2_accel_gyro_set_config(&bmi2);
/* Return 0 on error */
if (rslt != BMI2_OK) return 0;
/* Wait for init to complete */
delay(250);
/* Interrupt PINs configuration */
struct bmi2_int_pin_config data_int_cfg;
/* Configure interrupt to pin 1 */
data_int_cfg.pin_type = BMI2_INT1;
data_int_cfg.int_latch = BMI2_INT_NON_LATCH;
/* Interrupt output enabled */
data_int_cfg.pin_cfg[0].output_en = BMI2_INT_OUTPUT_ENABLE;
/* OpenDrain disabled */
data_int_cfg.pin_cfg[0].od = BMI2_INT_PUSH_PULL;
/* Interrupt signal set tp active high */
data_int_cfg.pin_cfg[0].lvl = BMI2_INT_ACTIVE_HIGH;
/* Interrupt input disabled */
data_int_cfg.pin_cfg[0].input_en = BMI2_INT_INPUT_DISABLE;
/* Set interrupt configuration with newly defined parameters */
rslt = bmi2_set_int_pin_config( &data_int_cfg, &bmi2);
/* Return 0 on error */
if (rslt != BMI2_OK) return 0;
/* Return 1 on successful */
return 1;
}
###########################################################################################################
imuInit always returns 0. Any idea what I'm doing wrong?
Thanks.
08-30-2021 03:47 PM
Hi,
It seems like you are using an Arduino MCU GPIO pin to witch on and off an LDO or MOSFET for BMI270 VDD and VDDIO, right? You may measure the voltage of those BMI270 GPIO pins after you switch it off to see if they are 0V or not. If yes, then you can switch on BMI270 again for initialization.
Thanks.