Segger Embedded Studi, SDK 15.2, Windows 10
Nordic NRF52DK PCA 10040 1. 2 .4
Hello again everyone, I have gotten farther with my previous issues of not being able to access individual register with the Bosch IMU (BMX055). I have used an example found here that specifically applies to my application for guidance as well. Another example of a read routine using the NRF52 and the same IMU was found here, but this routine also didn't work.
I have used code from this nordic thread for reading and writing functions through i2c but have had no success with them. I will post the code in question
#include <stdio.h> #include "boards.h" #include "app_util_platform.h" #include "app_error.h" #include "nrf_drv_twi.h" #include "nrf_delay.h" #include "nrf_log.h" #include "nrf_log_ctrl.h" #include "nrf_log_default_backends.h" #include "blebugIMU.h" /* TWI instance ID. */ #define TWI_INSTANCE_ID 0 /* Common addresses definition for temperature sensor. */ #define LM75B_ADDR (0x90U >> 1) #define LM75B_REG_TEMP 0x00U #define LM75B_REG_CONF 0x01U #define LM75B_REG_THYST 0x02U #define LM75B_REG_TOS 0x03U /* Mode for LM75B. */ #define NORMAL_MODE 0U /* Indicates if operation on TWI has ended. */ static volatile bool m_xfer_done = false; /* TWI instance. */ static const nrf_drv_twi_t m_twi = NRF_DRV_TWI_INSTANCE(TWI_INSTANCE_ID); /* Buffer for samples read from temperature sensor. */ static uint8_t m_sample; /** * @brief Function for setting active mode on MMA7660 accelerometer. */ /** * @brief Function for writing to registers on the MPU-6050. */ ret_code_t bmx055_I2C_register_write(uint8_t reg_addr, uint8_t * p_tx_data, uint8_t bytes) { ret_code_t ret_code; uint8_t tx_data[bytes+1]; tx_data[0] = reg_addr; for(uint8_t i = 0 ; i<bytes ; i++) { tx_data[i+1] = p_tx_data[i]; } ret_code = nrf_drv_twi_tx(&m_twi, BMX055_GYRO_ADDRESS, tx_data, sizeof(tx_data), false); return ret_code; } /** * @brief Function for reading from registers on the MPU-6050. */ ret_code_t bmx055_I2C_register_read( uint8_t reg_addr, uint8_t * p_rx_data, uint32_t bytes) { ret_code_t ret_code; ret_code = nrf_drv_twi_tx(&m_twi,BMX055_GYRO_ADDRESS, ®_addr, 1, false); if(ret_code != NRF_SUCCESS) { return ret_code; } ret_code = nrf_drv_twi_rx(&m_twi, BMX055_GYRO_ADDRESS, p_rx_data, bytes); return ret_code; } void bmx055_get_device_id (uint8_t * p_dev_id) { ret_code_t err_code; uint8_t rx_data; // Read the I2C Address of the BMX055 from the WHO_AM_I register err_code = bmx055_I2C_register_read(BMX055_ACC_WHOAMI,&rx_data,1); APP_ERROR_CHECK(err_code); *p_dev_id = rx_data; } void bmx055_read_acc(int16_t * p_x_val, int16_t * p_y_val, int16_t * p_z_val) { ret_code_t err_code; // Raw accelerometer measurements buffer uint8_t acc_data[6]; // Read the six accelerometer data registers starting from ACCEL_XOUT_H err_code = bmx055_I2C_register_read(BMX055_ACC_D_X_LSB,acc_data,sizeof(acc_data)); APP_ERROR_CHECK(err_code); /* Combine the two 8-bit data registers to a 16-bit value for each axis by left shifting ACCEL_xOUT_H eight times and OR it with ACCEL_xOUT_L. */ *p_x_val = (acc_data[0]<<8)|acc_data[1]; *p_y_val = (acc_data[2]<<8)|acc_data[3]; *p_z_val = (acc_data[4]<<8)|acc_data[5]; } /** * @brief Function for handling data from temperature sensor. * * @param[in] temp Temperature in Celsius degrees read from sensor. */ __STATIC_INLINE void data_handler(uint8_t temp) { NRF_LOG_INFO("Temperature: %d Celsius degrees.", temp); } void bmx055_read_gyro(int16_t * p_x_gyro, int16_t * p_y_gyro, int16_t * p_z_gyro) { ret_code_t err_code; uint8_t gyro_data[6]; //Read the 6 gyroscope data registers starting from GYRO_XOUT_H err_code = bmx055_I2C_register_read(BMX055_GYRO_RATE_X_LSB, gyro_data, sizeof(gyro_data)); APP_ERROR_CHECK(err_code); /* Combine the two 8-bit data registers to a 16-bit value for each axis by left shifting GYRO_xOUT_H eight times and OR it with GYRO_xOUT_L. */ *p_x_gyro = (gyro_data[0]<<8)|gyro_data[1]; *p_y_gyro = (gyro_data[2]<<8)|gyro_data[3]; *p_z_gyro = (gyro_data[4]<<8)|gyro_data[5]; } /** * @brief TWI events handler. */ void twi_handler(nrf_drv_twi_evt_t const * p_event, void * p_context) { switch (p_event->type) { case NRF_DRV_TWI_EVT_DONE: if (p_event->xfer_desc.type == NRF_DRV_TWI_XFER_RX) { data_handler(m_sample); } m_xfer_done = true; break; default: break; } } /** * @brief UART initialization. */ void twi_init (void) { ret_code_t err_code; const nrf_drv_twi_config_t twi_lm75b_config = { .scl = ARDUINO_SCL_PIN, .sda = ARDUINO_SDA_PIN, .frequency = NRF_DRV_TWI_FREQ_100K, .interrupt_priority = APP_IRQ_PRIORITY_HIGH, .clear_bus_init = false }; err_code = nrf_drv_twi_init(&m_twi, &twi_lm75b_config, twi_handler, NULL); APP_ERROR_CHECK(err_code); nrf_drv_twi_enable(&m_twi); } void bmx055_init (void) { ret_code_t err_code; uint8_t tx_data = 0xB6; // Write one to the BMX055_ACC_BGW_SOFTRESET and register to wake up the gyro and acc err_code = bmx055_I2C_register_write(BMX055_ACC_BGW_SOFTRESET, &tx_data, 1); APP_ERROR_CHECK(err_code); err_code = bmx055_I2C_register_write(BMX055_GYRO_BGW_SOFTRESET, &tx_data, 1); APP_ERROR_CHECK(err_code); } /** * @brief Function for reading data from temperature sensor. */ static void read_sensor_data() { m_xfer_done = false; /* Read 1 byte from the specified address - skip 3 bits dedicated for fractional part of temperature. */ ret_code_t err_code = nrf_drv_twi_rx(&m_twi, LM75B_ADDR, &m_sample, sizeof(m_sample)); APP_ERROR_CHECK(err_code); } /** * @brief Function for main application entry. */ int main(void) { APP_ERROR_CHECK(NRF_LOG_INIT(NULL)); NRF_LOG_DEFAULT_BACKENDS_INIT(); NRF_LOG_INFO("\r\nTWI sensor example started."); NRF_LOG_FLUSH(); twi_init(); bmx055_init(); uint8_t device_id; // bmx055_get_device_id(&device_id); /* int16_t x_val; int16_t y_val; int16_t z_val; bmx055_read_acc(&x_val, &y_val, &z_val); int16_t x_gyro; int16_t y_gyro; int16_t z_gyro; // Read Gyroscope Data bmx055_read_gyro(&x_gyro, &y_gyro, &z_gyro); */ while (true) { nrf_delay_ms(500); do { __WFE(); }while (m_xfer_done == false); read_sensor_data(); NRF_LOG_FLUSH(); } } /** @} */
As you will notice, I have commented out the other functions that I am not using and have narrowed down the fatal error occurrence to the instantiation of BMX055. It seems that my writing and reading routines themselves are to blame yet I don't know why. All of the pin addresses of the BMX055 are stored in a header file I put together which I will add below for reference. I would appreciate any help in getting these values sorted.
/* This header file was put tofether to include register and address definitions of the BMX055 IMU Pin defintions and useful enumerations are included */ #define BMX055_ACC_WHOAMI 0x00 // should return 0xFA //#define BMX055_ACC_Reserved 0x01 #define BMX055_ACC_D_X_LSB 0x02 #define BMX055_ACC_D_X_MSB 0x03 #define BMX055_ACC_D_Y_LSB 0x04 #define BMX055_ACC_D_Y_MSB 0x05 #define BMX055_ACC_D_Z_LSB 0x06 #define BMX055_ACC_D_Z_MSB 0x07 #define BMX055_ACC_D_TEMP 0x08 #define BMX055_ACC_INT_STATUS_0 0x09 #define BMX055_ACC_INT_STATUS_1 0x0A #define BMX055_ACC_INT_STATUS_2 0x0B #define BMX055_ACC_INT_STATUS_3 0x0C //#define BMX055_ACC_Reserved 0x0D #define BMX055_ACC_FIFO_STATUS 0x0E #define BMX055_ACC_PMU_RANGE 0x0F #define BMX055_ACC_PMU_BW 0x10 #define BMX055_ACC_PMU_LPW 0x11 #define BMX055_ACC_PMU_LOW_POWER 0x12 #define BMX055_ACC_D_HBW 0x13 #define BMX055_ACC_BGW_SOFTRESET 0x14 //#define BMX055_ACC_Reserved 0x15 #define BMX055_ACC_INT_EN_0 0x16 #define BMX055_ACC_INT_EN_1 0x17 #define BMX055_ACC_INT_EN_2 0x18 #define BMX055_ACC_INT_MAP_0 0x19 #define BMX055_ACC_INT_MAP_1 0x1A #define BMX055_ACC_INT_MAP_2 0x1B //#define BMX055_ACC_Reserved 0x1C //#define BMX055_ACC_Reserved 0x1D #define BMX055_ACC_INT_SRC 0x1E //#define BMX055_ACC_Reserved 0x1F #define BMX055_ACC_INT_OUT_CTRL 0x20 #define BMX055_ACC_INT_RST_LATCH 0x21 #define BMX055_ACC_INT_0 0x22 #define BMX055_ACC_INT_1 0x23 #define BMX055_ACC_INT_2 0x24 #define BMX055_ACC_INT_3 0x25 #define BMX055_ACC_INT_4 0x26 #define BMX055_ACC_INT_5 0x27 #define BMX055_ACC_INT_6 0x28 #define BMX055_ACC_INT_7 0x29 #define BMX055_ACC_INT_8 0x2A #define BMX055_ACC_INT_9 0x2B #define BMX055_ACC_INT_A 0x2C #define BMX055_ACC_INT_B 0x2D #define BMX055_ACC_INT_C 0x2E #define BMX055_ACC_INT_D 0x2F #define BMX055_ACC_FIFO_CONFIG_0 0x30 //#define BMX055_ACC_Reserved 0x31 #define BMX055_ACC_PMU_SELF_TEST 0x32 #define BMX055_ACC_TRIM_NVM_CTRL 0x33 #define BMX055_ACC_BGW_SPI3_WDT 0x34 //#define BMX055_ACC_Reserved 0x35 #define BMX055_ACC_OFC_CTRL 0x36 #define BMX055_ACC_OFC_SETTING 0x37 #define BMX055_ACC_OFC_OFFSET_X 0x38 #define BMX055_ACC_OFC_OFFSET_Y 0x39 #define BMX055_ACC_OFC_OFFSET_Z 0x3A #define BMX055_ACC_TRIM_GPO 0x3B #define BMX055_ACC_TRIM_GP1 0x3C //#define BMX055_ACC_Reserved 0x3D #define BMX055_ACC_FIFO_CONFIG_1 0x3E #define BMX055_ACC_FIFO_DATA 0x3F // BMX055 Gyroscope Registers #define BMX055_GYRO_WHOAMI 0x00 // should return 0x0F //#define BMX055_GYRO_Reserved 0x01 #define BMX055_GYRO_RATE_X_LSB 0x02 #define BMX055_GYRO_RATE_X_MSB 0x03 #define BMX055_GYRO_RATE_Y_LSB 0x04 #define BMX055_GYRO_RATE_Y_MSB 0x05 #define BMX055_GYRO_RATE_Z_LSB 0x06 #define BMX055_GYRO_RATE_Z_MSB 0x07 //#define BMX055_GYRO_Reserved 0x08 #define BMX055_GYRO_INT_STATUS_0 0x09 #define BMX055_GYRO_INT_STATUS_1 0x0A #define BMX055_GYRO_INT_STATUS_2 0x0B #define BMX055_GYRO_INT_STATUS_3 0x0C //#define BMX055_GYRO_Reserved 0x0D #define BMX055_GYRO_FIFO_STATUS 0x0E #define BMX055_GYRO_RANGE 0x0F #define BMX055_GYRO_BW 0x10 #define BMX055_GYRO_LPM1 0x11 #define BMX055_GYRO_LPM2 0x12 #define BMX055_GYRO_RATE_HBW 0x13 #define BMX055_GYRO_BGW_SOFTRESET 0x14 #define BMX055_GYRO_INT_EN_0 0x15 #define BMX055_GYRO_INT_EN_1 0x16 #define BMX055_GYRO_INT_MAP_0 0x17 #define BMX055_GYRO_INT_MAP_1 0x18 #define BMX055_GYRO_INT_MAP_2 0x19 #define BMX055_GYRO_INT_SRC_1 0x1A #define BMX055_GYRO_INT_SRC_2 0x1B #define BMX055_GYRO_INT_SRC_3 0x1C //#define BMX055_GYRO_Reserved 0x1D #define BMX055_GYRO_FIFO_EN 0x1E //#define BMX055_GYRO_Reserved 0x1F //#define BMX055_GYRO_Reserved 0x20 #define BMX055_GYRO_INT_RST_LATCH 0x21 #define BMX055_GYRO_HIGH_TH_X 0x22 #define BMX055_GYRO_HIGH_DUR_X 0x23 #define BMX055_GYRO_HIGH_TH_Y 0x24 #define BMX055_GYRO_HIGH_DUR_Y 0x25 #define BMX055_GYRO_HIGH_TH_Z 0x26 #define BMX055_GYRO_HIGH_DUR_Z 0x27 //#define BMX055_GYRO_Reserved 0x28 //#define BMX055_GYRO_Reserved 0x29 //#define BMX055_GYRO_Reserved 0x2A #define BMX055_GYRO_SOC 0x31 #define BMX055_GYRO_A_FOC 0x32 #define BMX055_GYRO_TRIM_NVM_CTRL 0x33 #define BMX055_GYRO_BGW_SPI3_WDT 0x34 //#define BMX055_GYRO_Reserved 0x35 #define BMX055_GYRO_OFC1 0x36 #define BMX055_GYRO_OFC2 0x37 #define BMX055_GYRO_OFC3 0x38 #define BMX055_GYRO_OFC4 0x39 #define BMX055_GYRO_TRIM_GP0 0x3A #define BMX055_GYRO_TRIM_GP1 0x3B #define BMX055_GYRO_BIST 0x3C #define BMX055_GYRO_FIFO_CONFIG_0 0x3D #define BMX055_GYRO_FIFO_CONFIG_1 0x3E // BMX055 magnetometer registers #define BMX055_MAG_WHOAMI 0x40 // should return 0x32 #define BMX055_MAG_Reserved 0x41 #define BMX055_MAG_XOUT_LSB 0x42 #define BMX055_MAG_XOUT_MSB 0x43 #define BMX055_MAG_YOUT_LSB 0x44 #define BMX055_MAG_YOUT_MSB 0x45 #define BMX055_MAG_ZOUT_LSB 0x46 #define BMX055_MAG_ZOUT_MSB 0x47 #define BMX055_MAG_ROUT_LSB 0x48 #define BMX055_MAG_ROUT_MSB 0x49 #define BMX055_MAG_INT_STATUS 0x4A #define BMX055_MAG_PWR_CNTL1 0x4B #define BMX055_MAG_PWR_CNTL2 0x4C #define BMX055_MAG_INT_EN_1 0x4D #define BMX055_MAG_INT_EN_2 0x4E #define BMX055_MAG_LOW_THS 0x4F #define BMX055_MAG_HIGH_THS 0x50 #define BMX055_MAG_REP_XY 0x51 #define BMX055_MAG_REP_Z 0x52 // BMX055 magnetometer registers #define BMX055_MAG_WHOAMI 0x40 // should return 0x32 #define BMX055_MAG_Reserved 0x41 #define BMX055_MAG_XOUT_LSB 0x42 #define BMX055_MAG_XOUT_MSB 0x43 #define BMX055_MAG_YOUT_LSB 0x44 #define BMX055_MAG_YOUT_MSB 0x45 #define BMX055_MAG_ZOUT_LSB 0x46 #define BMX055_MAG_ZOUT_MSB 0x47 #define BMX055_MAG_ROUT_LSB 0x48 #define BMX055_MAG_ROUT_MSB 0x49 #define BMX055_MAG_INT_STATUS 0x4A #define BMX055_MAG_PWR_CNTL1 0x4B #define BMX055_MAG_PWR_CNTL2 0x4C #define BMX055_MAG_INT_EN_1 0x4D #define BMX055_MAG_INT_EN_2 0x4E #define BMX055_MAG_LOW_THS 0x4F #define BMX055_MAG_HIGH_THS 0x50 #define BMX055_MAG_REP_XY 0x51 #define BMX055_MAG_REP_Z 0x52 /* Trim Extended Registers */ #define BMM050_DIG_X1 0x5D // needed for magnetic field calculation #define BMM050_DIG_Y1 0x5E #define BMM050_DIG_Z4_LSB 0x62 #define BMM050_DIG_Z4_MSB 0x63 #define BMM050_DIG_X2 0x64 #define BMM050_DIG_Y2 0x65 #define BMM050_DIG_Z2_LSB 0x68 #define BMM050_DIG_Z2_MSB 0x69 #define BMM050_DIG_Z1_LSB 0x6A #define BMM050_DIG_Z1_MSB 0x6B #define BMM050_DIG_XYZ1_LSB 0x6C #define BMM050_DIG_XYZ1_MSB 0x6D #define BMM050_DIG_Z3_LSB 0x6E #define BMM050_DIG_Z3_MSB 0x6F #define BMM050_DIG_XY2 0x70 #define BMM050_DIG_XY1 0x71 // Seven-bit device addresses are ACC = 0x18, GYRO = 0x68, MAG = 0x10 #define BMX055_ACC_ADDRESS 0x18 // Address of BMX055 accelerometer #define BMX055_GYRO_ADDRESS 0x68 // Address of BMX055 gyroscope #define BMX055_MAG_ADDRESS 0x10 // Address of BMX055 magnetometer #define MS5637_ADDRESS 0x76 // Address of altimeter #define AFS_2G 0x03 #define AFS_4G 0x05 #define AFS_8G 0x08 #define AFS_16G 0x0C