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