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, ®_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);
}
}
... View more