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?