I am trying to get a BMX160 working over SPI. I was following this post to make this code using the SPI example from the SDK as a basis. I am using SDK 15.3 with a nRF52840 in SES.
Below is my code
#include "nrf_drv_spi.h"
#include "app_util_platform.h"
#include "nrf_gpio.h"
#include "nrf_delay.h"
#include "boards.h"
#include "app_error.h"
#include <string.h>
#include "nrf_log.h"
#include "nrf_log_ctrl.h"
#include "nrf_log_default_backends.h"
#include "bmi160.h"
#include "bmi160_defs.h"
#define SPI_INSTANCE 0 /**< SPI instance index. */
static const nrf_drv_spi_t spi = NRF_DRV_SPI_INSTANCE(SPI_INSTANCE); /**< SPI instance. */
static volatile bool spi_xfer_done; /**< Flag used to indicate that SPI instance completed the transfer. */
struct bmi160_dev sensor;
static uint8_t filler= 0xFF;
/**
* @brief SPI user event handler.
* @param event
*/
void spi_event_handler(nrf_drv_spi_evt_t const * p_event,
void * p_context)
{
spi_xfer_done = true;
NRF_LOG_INFO("Transfer completed.");
}
void spi_init(void)
{
ret_code_t err_code;
// GPIO PIN SETTINGS
nrf_gpio_cfg_output(IMU_SPI_CS);
nrf_gpio_cfg_output(IMU_SPI_SDO);
nrf_gpio_cfg_output(IMU_SPI_SCK);
nrf_gpio_cfg_input(IMU_SPI_SDI, NRF_GPIO_PIN_PULLDOWN);
nrf_gpio_pin_clear(IMU_SPI_SDO);
nrf_gpio_pin_clear(IMU_SPI_SCK);
nrf_gpio_pin_set(IMU_SPI_CS);
// init spi
nrf_drv_spi_config_t spi_config = NRF_DRV_SPI_DEFAULT_CONFIG;
spi_config.ss_pin = IMU_SPI_CS;
spi_config.miso_pin = IMU_SPI_SDI;
spi_config.mosi_pin = IMU_SPI_SDO;
spi_config.sck_pin = IMU_SPI_SCK;
err_code = nrf_drv_spi_init(&spi, &spi_config, spi_event_handler/*NULL*/, NULL);
APP_ERROR_CHECK(err_code);
}
int8_t spi_read_transfer(uint8_t dev_id, uint8_t reg_addr, uint8_t *reg_data, uint16_t length)
{
ret_code_t ret;
uint8_t read_temp[length+1];
ret = nrf_drv_spi_transfer(&spi, ®_addr, 1, read_temp, length+1);
nrf_delay_ms(5);
for (int i=1; i<length+1; i++)
{
reg_data[i-1] = read_temp[i];
}
return (int8_t)ret;
}
int8_t spi_write_transfer(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];
write_temp[0] = reg_addr;
for (int i=1; i<length+1; i++)
{
write_temp[i] = reg_data[i-1];
}
ret = nrf_drv_spi_transfer(&spi, write_temp, length+1, &filler, 1);
nrf_delay_ms(5);
return (int8_t)ret;
}
void init_bmi_sensor(void)
{
nrf_gpio_pin_set(LEDB_3);
sensor.id = 1 ;
sensor.interface = BMI160_SPI_INTF;
sensor.read = spi_read_transfer;
sensor.write = spi_write_transfer;
sensor.delay_ms = nrf_delay_ms;
int8_t rslt = BMI160_OK;
rslt = bmi160_init(&sensor);
nrf_gpio_pin_clear(LEDB_3);
}
int main(void)
{
APP_ERROR_CHECK(NRF_LOG_INIT(NULL));
NRF_LOG_DEFAULT_BACKENDS_INIT();
nrf_gpio_cfg_output(LEDB_3);
nrf_gpio_cfg_output(LEDG_2);
nrf_gpio_pin_clear(LEDB_3);
nrf_gpio_pin_clear(LEDG_2);
spi_init();
init_bmi_sensor();
NRF_LOG_INFO("SPI started.");
/* Call the "bmi160_init" API as a prerequisite before performing self test
* since invoking self-test will reset the sensor */
int8_t rslt;
rslt = bmi160_perform_self_test(BMI160_ACCEL_ONLY, &sensor);
/* Utilize the enum BMI160_GYRO_ONLY instead of BMI160_ACCEL_ONLY
to perform self test for gyro */
if (rslt == BMI160_OK) {
NRF_LOG_INFO("ACCEL SELF TEST RESULT SUCCESS");
} else {
NRF_LOG_INFO("ACCEL SELF TEST RESULT FAIL");
}
while(1)
{
int8_t rslt = BMI160_OK;
uint8_t reg_addr = BMI160_CHIP_ID_ADDR;
uint8_t data;
uint16_t len = 1;
rslt = bmi160_get_regs(reg_addr, &data, len, &sensor);
NRF_LOG_INFO("rslt = %d", rslt);
NRF_LOG_INFO("data = %d", data);
NRF_LOG_FLUSH();
nrf_delay_ms(500);
}
}
And below is my output in the console.

I am not sure if I have made and error in my code to cause a test fail and not give me any outputs for the chip id.
I have also used this post on Bosch's forum as a reference for difference between BMI160 and BMX160.
Is there anything in my code that could be causing an error that I can fix?