Bosch Sensortec Community

    cancel
    Showing results for 
    Search instead for 
    Did you mean: 

    BMI160 gyro power configure problem

    paradigmIOT
    New Poster

    BMI160 gyro power configure problem

    So I've gotten the BMI160 chip so successfully read out its accelerometer data with no problem, but when I set the power mode for the gyroscope I get no outputs and there are no errors in the error register.

    Without configuring the gyro_cfg.power to BMI160_GYRO_NORMAL_MODE, I read that the PMU register has the acceleromoter in normal mode, the Status register reads accelerometer data is ready and NVM is ready as well and I can get accelerations data happily all day long.

    When I configure the gyro_cfg.power the PMU Register reads 0, all suspended, and only the NVM is ready in the Status register. Still no errors. What's going on here? What am I missing that's causing the problem?

     

     

    #define SPI_BUFFER_SIZE 20
    #define SPI_INSTANCE  0                                             /**< SPI instance index. */
    static const nrf_drv_spi_t spi = NRF_DRV_SPI_INSTANCE(SPI_INSTANCE);/**< SPI instance. */
    static uint8_t spi_tx_buf[SPI_BUFFER_SIZE];                         /**< TX buffer. */
    static uint8_t spi_rx_buf[SPI_BUFFER_SIZE];                         /**< RX buffer. */
    bool volatile spi_xfer_done = false;
    
    void user_delay_ms(uint32_t period) {
      nrf_delay_ms(period);
    }
    
    //function is called when spi transfer is complete
    void spi_event_handler(nrf_drv_spi_evt_t const *p_event, void *p_context)
    {
        //setting flag to true unblocks
        spi_xfer_done = true;
        // DPRINTF("Received: 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x\n",
        //     spi_rx_buf[0], spi_rx_buf[1], spi_rx_buf[2], spi_rx_buf[3], spi_rx_buf[4],
        //     spi_rx_buf[5], spi_rx_buf[6], spi_rx_buf[7], spi_rx_buf[8], spi_rx_buf[9],
        //     spi_rx_buf[10], spi_rx_buf[11], spi_rx_buf[12], spi_rx_buf[13], spi_rx_buf[14],
        //     spi_rx_buf[15], spi_rx_buf[16], spi_rx_buf[17], spi_rx_buf[18], spi_rx_buf[19]
        //     );
    }
    
    //send spi command and waits for return - signaled by spi_xfer_done being true
    int8_t spi_read(uint8_t dev_id, uint8_t reg_addr, uint8_t *reg_data, uint16_t length){
    
        ret_code_t ret ;
        reg_addr = reg_addr | 0x80;
        memset(spi_rx_buf, 0, SPI_BUFFER_SIZE);
        uint8_t * read_temp = spi_rx_buf;
        spi_xfer_done = false;
        ret = nrf_drv_spi_transfer(&spi, &reg_addr, 1, read_temp, length + 1 ) ;    
        while (!spi_xfer_done)
        {
            __WFE();
        }
        
        memcpy((void*)reg_data, (void*)(read_temp+1), length);
        
        // DPRINTF("RSLT: %d\n", ret);
        nrf_delay_ms(1);
        return (int8_t)ret; 
    }
    
    //send a spi command and does not listen or wait for a return
    int8_t spi_write(uint8_t dev_id, uint8_t reg_addr, uint8_t *reg_data, uint16_t length){
    
        ret_code_t ret;
        // uint8_t write_temp[ length + 1 ] ;
        spi_tx_buf[0] = reg_addr  & 0x7F;
        memcpy((void*)(spi_tx_buf+1), (void*)(reg_data), length);
        
        spi_xfer_done = false;
        ret = nrf_drv_spi_transfer(&spi, spi_tx_buf, length + 1, NULL, 0 ) ;
        while (!spi_xfer_done)
        {
            __WFE();
        }
        
        // DPRINTF("RSLT: %d\n", ret);
        return (int8_t)ret; 
    }
    
    void imu_init(void)
    {
        //initialize spi on nRF
        nrf_drv_spi_config_t spi_config = NRF_DRV_SPI_DEFAULT_CONFIG;
        spi_config.ss_pin = PIN_SS;
        spi_config.miso_pin = PIN_MISO;
        spi_config.mosi_pin = PIN_MOSI;
        spi_config.sck_pin = PIN_SCLK;
        spi_config.frequency = NRF_DRV_SPI_FREQ_1M;
        spi_config.mode = NRF_DRV_SPI_MODE_0;
        APP_ERROR_CHECK(nrf_drv_spi_init(&spi, &spi_config, spi_event_handler, NULL));
    
        //initialize BMI160 sensor
        struct bmi160_dev sensor;
        /* You may assign a chip select identifier to be handled later */
        sensor.id = 0;
        sensor.interface = BMI160_SPI_INTF;
        sensor.read = spi_read;
        sensor.write = spi_write;
        sensor.delay_ms = user_delay_ms;
    
        int8_t rslt = BMI160_OK;
        rslt = bmi160_init(&sensor);
        if(rslt != 0) {
            DPRINTF("Error on Sensor SPI\n");
        } else {
            DPRINTF("IMU SPI Enabled\n");
        }
        /* After the above function call, accel_cfg and gyro_cfg parameters in the device 
        structure are set with default values, found in the datasheet of the sensor */
    
        //foc
        uint8_t reg_addr = 0x69;
        uint8_t data = 0b11111111;
        // rslt = bmi160_set_regs(reg_addr, &data, 1, &sensor);
        // nrf_delay_ms(300); //page 45 says foc needs 250ms to configure
        // bmi160_get_regs(reg_addr, &data, 1, &sensor);
        // DPRINTF("FOC: %d\n", rslt);
        // DPRINTF("FOC register: %d\n", data);
    
        // reg_addr = 0x7E;
        // data = 0x03;
        // rslt = bmi160_set_regs(reg_addr, &data, 1, &sensor);
        // nrf_delay_ms(300); //page 45 says foc needs 250ms to configure
    
        /* Select the Output data rate, range of accelerometer sensor */
        sensor.accel_cfg.odr = BMI160_ACCEL_ODR_100HZ;
        sensor.accel_cfg.range = BMI160_ACCEL_RANGE_2G;
        sensor.accel_cfg.bw = BMI160_ACCEL_BW_NORMAL_AVG4;
        /* Select the power mode of accelerometer sensor */
        sensor.accel_cfg.power = BMI160_ACCEL_NORMAL_MODE;
        /* Select the Output data rate, range of Gyroscope sensor */
        sensor.gyro_cfg.odr = BMI160_GYRO_ODR_200HZ;
        sensor.gyro_cfg.range = BMI160_GYRO_RANGE_250_DPS;
        sensor.gyro_cfg.bw = BMI160_GYRO_BW_NORMAL_MODE;
        /* Select the power mode of Gyroscope sensor */
        // sensor.gyro_cfg.power = BMI160_GYRO_NORMAL_MODE;
        /* Set the sensor configuration */
        rslt = bmi160_set_sens_conf(&sensor);
        if(rslt != 0) {
            DPRINTF("Error Configuring Sensor: %d\n", rslt);
        } else {
            DPRINTF("IMU Initialized\n");
        }
        reg_addr = 0x03;
        bmi160_get_regs(reg_addr, &data, 1, &sensor);
        DPRINTF("Power register: %d\n", data);
    
        reg_addr = 0x00;
        bmi160_get_regs(reg_addr, &data, 1, &sensor);
        DPRINTF("Chip ID register: %d\n", data);
    
        reg_addr = 0x1B;
        bmi160_get_regs(reg_addr, &data, 1, &sensor);
        DPRINTF("Status register: %d\n", data);
    
        //read initial gyro, accel and time data from imu
        struct bmi160_sensor_data accel;
        struct bmi160_sensor_data gyro;
        while(1) {
            bmi160_get_regs(reg_addr, &data, 1, &sensor);
            DPRINTF("Status register: %d\n", data);
    
            bmi160_get_sensor_data((BMI160_ACCEL_SEL | BMI160_GYRO_SEL), &accel, &gyro, &sensor);
            DPRINTF("Accel: %d %d %d\t\t", accel.x, accel.y, accel.z);
            DPRINTF("Gyro: %d %d %d\n", gyro.x, gyro.y, gyro.z);
            nrf_delay_ms(1000);
        }
        
    }

     

    Tags (1)
    1 REPLY 1
    o_o
    Contributor

    Re: BMI160 gyro power configure problem

    I see 3 potential issues with your code.
    1) the gyro power configuration is commented out
    2) the gyroscope can take up to 80ms to start, but I do not see any delay in your code before checking the register.
    3) Please confirm the accuracy of your delay function, and that the 450us delay in suspend modes between writes is respected.

    o_o
    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