My implementation of Bosh BMI160 Only I2C is tested so far.
Dependents: test_BMI160 TFT_test_MAX32630FTHR
Revision 0:9aed6f5a35c0, committed 2017-08-25
- Comitter:
- Rhyme
- Date:
- Fri Aug 25 05:07:26 2017 +0000
- Child:
- 1:d56df81c389b
- Commit message:
- Register bit description entered
Changed in this revision
| BMI160.cpp | Show annotated file Show diff for this revision Revisions of this file |
| BMI160.h | Show annotated file Show diff for this revision Revisions of this file |
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/BMI160.cpp Fri Aug 25 05:07:26 2017 +0000
@@ -0,0 +1,553 @@
+#include "mbed.h"
+#include "BMI160.h"
+
+/* register address defintions */
+#define REG_CHIP_ID 0x00 /* chip id */
+#define REG_ERR_REG 0x02
+#define REG_PMU_STATUS 0x03
+#define REG_DATA_0 0x04 /* MAG_X_LSB */
+#define REG_DATA_1 0x05 /* MAG_X_MSB */
+#define REG_DATA_2 0x06 /* MAG_Y_LSB */
+#define REG_DATA_3 0x07 /* MAG_Y_MSB */
+#define REG_DATA_4 0x08 /* MAG_Z_LSB */
+#define REG_DATA_5 0x09 /* MAG_Z_MSB */
+#define REG_DATA_6 0x0A /* RHALL_LSB */
+#define REG_DATA_7 0x0B /* RHALL_MSB */
+#define REG_DATA_8 0x0C /* GRY_X_LSB */
+#define REG_DATA_9 0x0D /* GRY_X_MSB */
+#define REG_DATA_10 0x0E /* GRY_Y_LSB */
+#define REG_DATA_11 0x0F /* GRY_Y_MSB */
+#define REG_DATA_12 0x10 /* GRY_Z_LSB */
+#define REG_DATA_13 0x11 /* GRY_Z_MSB */
+#define REG_DATA_14 0x12 /* ACC_X_LSB */
+#define REG_DATA_15 0x13 /* ACC_X_MSB */
+#define REG_DATA_16 0x14 /* ACC_Y_LSB */
+#define REG_DATA_17 0x15 /* ACC_Y_MSB */
+#define REG_DATA_18 0x16 /* ACC_Z_LSB */
+#define REG_DATA_19 0x17 /* ACC_Z_MSB */
+#define REG_SENSORTIME_0 0x18 /* SENSOR_TIME_LSB */
+#define REG_SENSORTIME_1 0x19 /* SENSOR_TIME_CSB */
+#define REG_SENSORTIME_2 0x1A /* SENSOR_TIME_MSB */
+#define REG_STATUS 0x1B
+#define REG_INT_STATUS_0 0x1C
+#define REG_INT_STATUS_1 0x1D
+#define REG_INT_STATUS_2 0x1E
+#define REG_INT_STATUS_3 0x1F
+#define REG_TEMPERATURE_0 0x20
+#define REG_TEMPERATURE_1 0x21
+#define REG_FIFO_LENGTH_0 0x22
+#define REG_FIFO_LENGTH_1 0x23
+#define REG_FIFO_DATA 0x24
+#define REG_ACC_CONF 0x40
+#define REG_ACC_RANGE 0x41
+#define REG_GYR_CONF 0x42
+#define REG_GYR_RANGE 0x43
+#define REG_MAG_CONF 0x44
+#define REG_FIFO_DOWNS 0x45
+#define REG_FIFO_CONFIG_0 0x46
+#define REG_FIFO_CONFIG_1 0x47
+#define REG_MAG_IF_0 0x4B
+#define REG_MAG_IF_1 0x4C
+#define REG_MAG_IF_2 0x4D
+#define REG_MAG_IF_3 0x4E
+#define REG_MAG_IF_4 0x4F
+#define REG_INT_EN_0 0x50
+#define REG_INT_EN_1 0x51
+#define REG_INT_EN_2 0x52
+#define REG_INT_OUT_CTRL 0x53
+#define REG_INT_LATCH 0x54
+#define REG_INT_MAP_0 0x55
+#define REG_INT_MAP_1 0x56
+#define REG_INT_MAP_2 0x57
+#define REG_INT_DATA_0 0x58
+#define REG_INT_DATA_1 0x59
+#define REG_LOWHIGHT_0 0x5A
+#define REG_LOWHIGHT_1 0x5B
+#define REG_LOWHIGHT_2 0x5C
+#define REG_LOWHIGHT_3 0x5D
+#define REG_LOWHIGHT_4 0x5E
+#define REG_INT_MOTION_0 0x5F
+#define REG_INT_MOTION_1 0x60
+#define REG_INT_MOTION_2 0x61
+#define REG_INT_MOTION_3 0x62
+#define REG_INT_TAP_0 0x63
+#define REG_INT_TAP_1 0x64
+#define REG_INT_ORIENT_0 0x65
+#define REG_INT_ORIENT_1 0x66
+#define REG_INT_FLAT_0 0x67
+#define REG_INT_FLAT_1 0x68
+#define REG_FOC_CONF 0x69
+#define REG_CONF 0x6A
+#define REG_IF_CONF 0x6B
+#define REG_PMU_TRIGGER 0x6C
+#define REG_SELF_TEST 0x6D
+#define REG_NV_CONF 0x70
+#define REG_OFFSET_0 0x71
+#define REG_OFFSET_1 0x72
+#define REG_OFFSET_2 0x73
+#define REG_OFFSET_3 0x74
+#define REG_OFFSET_4 0x75
+#define REG_OFFSET_5 0x76
+#define REG_OFFSET_6 0x77
+#define REG_STEP_CNT_0 0x78
+#define REG_STEP_CNT_1 0x79
+#define REG_STEP_CONF_0 0x7A
+#define REG_STEP_CONF_1 0x7B
+#define REG_CMD 0x7E
+
+/* 0x00 CHIP_ID reset value = 0xD1 */
+/* 0x02 ERR_REG
+ * bit[7] mag_drdy_err
+ * bit[6] drop_cmd_err
+ * bit[5] i2c_fail_err
+ * bit[4:1] err_code
+ * bit[0] fatal_err
+ */
+/* 0x03 PMU_STATUS
+ * bit[7:6] (reserved)
+ * bit[5:4] acc_pmu_status
+ * bit[3:2] gyr_pmu_status
+ * bit[1:0] mag_pmu_status
+ */
+/* 0x04 DATA_0 : MAG_X[7:0] */
+/* 0x05 DATA_1 : MAG_X[15:8] */
+/* 0x06 DATA_2 : MAG_Y[7:0] */
+/* 0x07 DATA_3 : MAG_Y[15:8] */
+/* 0x08 DATA_4 : MAG_Z[7:0] */
+/* 0x09 DATA_5 : MAG_Z[15:8] */
+/* 0x0A DATA_6 : RHALL[7:0] */
+/* 0x0B DATA_7 : RHALL[15:8] */
+/* 0x0C DATA_8 : GYR_X[7:0] */
+/* 0x0D DATA_9 : GYR_X[15:8] */
+/* 0x0E DATA_10 : GYR_Y[7:0] */
+/* 0x0F DATA_11 : GYR_Y[15:8] */
+/* 0x10 DATA_12 : GYR_Z[7:0] */
+/* 0x11 DATA_13 : GYR_Z[15:8] */
+/* 0x12 DATA_14 : ACC_X[7:0] */
+/* 0x13 DATA_15 : ACC_X[15:8] */
+/* 0x14 DATA_16 : ACC_Y[7:0] */
+/* 0x15 DATA_17 : ACC_Y[15:8] */
+/* 0x16 DATA_18 : ACC_Z[7:0] */
+/* 0x17 DATA_19 : ACC_Z[15:8] */
+/* 0x18 SENSORTIME_0 : sensor_time[7:0] */
+/* 0x19 SENSORTIME_1 : sensor_time[15:8] */
+/* 0x1A SENSORTIME_2 : sensor_time[23:16] */
+/* 0x1B STATUS
+ * bit[7] drdy_acc
+ * bit[6] drdy_gyr
+ * bit[5] drfy_mag
+ * bit[4] nvm_rdy
+ * bit[3] foc_rdy
+ * bit[2] mag_man_op
+ * bit[1] gry_self_test_of
+ * bit[0] (reserved)
+ */
+/* 0x1C INT_STATUS_0
+ * bit[7] flat_int
+ * bit[6] orient_int
+ * bit[5] s_tap_int
+ * bit[4] d_tap_int
+ * bit[3] pmu_trigger_int
+ * bit[2] anym_int
+ * bit[1] sigmot_int
+ * bit[0] step_int
+ */
+/* 0x1D INT_STATUS_1
+ * bit[7] nomo_int
+ * bit[6] fwm_int
+ * bit[5] ffull_int
+ * bit[4] drdy_int
+ * bit[3] lowg_int
+ * bit[2] highg_int
+ * bit[1:0] (reserved)
+ */
+/* 0x1E INT_STATUS_2
+ * bit[7] tap_sign
+ * bit[6] tap_first_z
+ * bit[5] tap_first_y
+ * bit[4] tap_first_x
+ * bit[3] anym_sign
+ * bit[2] anym_first_z
+ * bit[1] anym_first_y
+ * bit[0] anym_first_x
+ */
+/* 0x1F INT_STATUS_3
+ * bit[7] flat
+ * bit[6] orient_2
+ * bit[5] orient_1
+ * bit[4] orient_0
+ * bit[3] high_sign
+ * bit[2] high_first_z
+ * bit[1] high_first_y
+ * bit[0] high_first_x
+ */
+/* 0x20 TEMPERATURE_0 temperature[7:0] */
+/* 0x21 TEMPERATURE_1 reset value = 0x80 temperature[15:8] */
+/* 0x22 FIFO_LENGTH_0 fifo_byte_counter[7:0] */
+/* 0x23 FIFO_LENGTH_1
+ * bit[7:3] (reserved)
+ * bit[2:0] fifo_byte_counter[10:8]
+ */
+/* 0x40 ACC_CONF reset value 0x28
+ * bit[7] acc_us
+ * bit[6:4] acc_bwp
+ * bit[3:0] acc_odr
+ */
+/* 0x41 ACC_RANGE reset value = 0x03
+ * bit[7:4] (reserved)
+ * bit[3:0] acc_range
+ */
+/* 0x42 GYR_CONF reset value = 0x28
+ * bit[7:6] (reserved)
+ * bit[5:4] gyr_bwp
+ * bit[3:0] gyr_odr
+ */
+/* 0x43 GYR_RANGE
+ * bit[7:3] (reserved)
+ * bit[2:0] gyr_range
+ */
+/* 0x44 MAG_CONF reset value = 0x0B
+ * bit[7:4] (reserved)
+ * bit[3:0] mag_odr
+ */
+/* 0x45 FIFO_DOWNS reset value = 0x88
+ * bit[7] acc_fifo_filt_data
+ * bit[6:4] acc_fifo_downs
+ * bit[3] gyr_fifo_filt_data
+ * bit[2:0] gyr_fifo_downs
+ */
+/* 0x46 FIFO_CONFIG_0 reset value = 0x80
+ * bit[7:0] fifo_water_mark
+ */
+/* 0x47 FIFO_CONFIG_1 reset value = 0x10
+ * bit[7] fifo_gyr_en
+ * bit[6] fifo_acc_en
+ * bit[5] fifo_mag_en
+ * bit[4] fifo_header_en
+ * bit[3] fifo_tag_int1_en
+ * bit[2] fifo_tag_int2_en
+ * bit[1] fifo_time_en
+ * bit[0] (reserved)
+ */
+/* 0x4B MAG_IF_0 reset value = 0x20
+ * bit[7:1] i2c_device_addr
+ */
+/* 0x4C MAG_IF_1 reset value = 0x80
+ * bit[7] mag_manual_en
+ * bit[6] (reserved)
+ * bit[5:2] mag_offset
+ * bit[1:0] mag_rd_burst
+ */
+/* 0x4D MAG_IF_2 reset value = 0x42
+ * bit[7:0] read_addr
+ */
+/* 0x4E MAG_IF_3 reset value = 0x4C
+ * bit[7:0] write_addr
+ */
+/* 0x4F MAG_IF_4 bit[7:0] write data */
+/* 0x50 INT_EN_0
+ * bit[7] int_flat_en
+ * bit[6] int_orient_en
+ * bit[5] int_s_tap_en
+ * bit[4] int_d_tap_en
+ * bit[3] (reserved)
+ * bit[2] int_anymo_z_en
+ * bit[1] int_anymo_y_en
+ * bit[0] int_anymo_x_en
+ */
+/* 0x51 INT_EN_1
+ * bit[7] (reserved)
+ * bit[6] int_fwm_en
+ * bit[5] int_ffull_en
+ * bit[4] int_drdy_en
+ * bit[3] int_low_en
+ * bit[2] int_highg_z_en
+ * bit[1] int_highg_y_en
+ * bit[0] int_highg_x_en
+ */
+/* 0x52 INT_EN_2
+ * bit[7:4] (reserved)
+ * bit[3] int_step_det_en
+ * bit[2] int_nomoz_en
+ * bit[1] int_nomoy_en
+ * bit[0] int_nomox_en
+ */
+/* 0x53 INT_OUT_CTRL
+ * bit[7] int2_output_en
+ * bit[6] int2_od
+ * bit[5] int2_lvl
+ * bit[4] int2_edge_ctrl
+ * bit[3] int1_output_en
+ * bit[2] int1_od
+ * bit[1] int1_lvl
+ * bit[0] itn1_edge_ctrl
+ */
+/* 0x54 INT_LATCH
+ * bit[7:6] (reserved)
+ * bit[5] int2_input_en
+ * bit[4] int1_input_en
+ * bit[3:0] int_latch
+ */
+/* 0x55 INT_MAP_0
+ * bit[7] int1_flat
+ * bit[6] int1_orient
+ * bit[5] int1_s_tap
+ * bit[4] int1_d_tap
+ * bit[3] int1_nomotion
+ * bit[2] int1_anymotion
+ * bit[1] int1_highg
+ * bit[0] int1_lowg_step
+ */
+/* 0x56 INT_MAP_1
+ * bit[7] int1_drdy
+ * bit[6] int1_fwm
+ * bit[5] int1_ffull
+ * bit[4] int1_pmu_trig
+ * bit[3] int2_drdy
+ * bit[2] itn2_fwm
+ * bit[1] int2_ffull
+ * bit[0] int2_pmu_trig
+ */
+/* 0x57 INT_MAP_2
+ * bit[7] int2_flat
+ * bit[6] int2_orient
+ * bit[5] int2_s_tap
+ * bit[4] int2_d_tap
+ * bit[3] int2_nomotion
+ * bit[2] int2_anymotion
+ * bit[1] int2_highg
+ * bit[0] int2_lowg_steop
+ */
+/* 0x58 INT_DATA_0
+ * bit[7] int_low_high_src
+ * bit[6:4] (reserved)
+ * bit[3] int_tap_src
+ * bit[2:0] (reserved)
+ */
+/* 0x59 INT_DATA_1
+ * bit[7] int_motion_src
+ * bit[6:0] (reseved)
+ */
+/* 0x5A INT_LOWHIGH_0 reset value = 0x07
+ * bit[7:0] int_low_dur
+ */
+/* 0x5B INT_LOWHIGH_1 reset value = 0x30
+ * bit[7:0] int_low_th
+ */
+/* 0x5C INT_LOWHIGH_2 reset value = 0x81
+ * bit[7:6] int_high_hy
+ * bit[5:3] (reserved)
+ * bit[2] int_low_mode
+ * bit[1:0] int_low_hy
+ */
+/* 0x5D INT_LOWHIGH_3 reset value = 0x0B
+ * bit[7:0] int_high_dur
+ */
+/* 0x5E INT_LOWHIGH_4 reset value = 0xC0
+ * bit[7:0] int_high_th
+ */
+/* 0x5F INT_MOTION_0
+ * bit[7:2] int_slo_nomo_dur
+ * bit[1:0] int_anym_dur
+ */
+/* 0x60 INT_MOTION_1 reset value = 0x14
+ * bit[7:0] int_anymo_th
+ */
+/* 0x61 INT_MOTION_2 reset value = 0x14
+ * bit[7:0] int_slo_nomo_th
+ */
+/* 0x62 INT_MOTION_3 reset value = 0x24
+ * bit[7:6] (reserved)
+ * bit[5:4] int_sig_mot_proof
+ */
+/* 0x63 INT_TAP_0 reset value = 0x04
+ * bit[7] int_tap_quiet
+ * bit[6] int_tap_shock
+ * bit[5:3] (reserved)
+ * bit[2:0] int_tap_dur
+ */
+/* 0x64 INT_TAP_1 reset value = 0x0A
+ * bit[7:5] (reserved)
+ * bit[4:0] int_tap_th
+ */
+/* 0x65 INT_ORIENT_0 reset value = 0x18
+ * bit[7:4] int_orient_hy
+ * bit[3:2] int_orient_blocking
+ * bit[1:0] int_orient_mode
+ */
+/* 0x66 INT_ORIENT_1 reset value = 0x48
+ * bit[7] int_orient_axes_ex
+ * bit[6] int_orient_ud_en
+ * bit[5:0] int_orient_theta
+ */
+/* 0x67 INT_FLAT_0 reset value = 0x08
+ * bit[7:6] (reserved)
+ * bit[5:0] int_flat_theta
+ */
+/* 0x68 INT_FLAT_1 reset value = 0x11
+ * bit[7:6] (reserved)
+ * bit[5:4] int_flat_hold
+ * bit[3:0] int_flat_hy
+ */
+/* 0x69 FOC_CONF
+ * bit[7] (reserved)
+ * bit[6] foc_gyr_en
+ * bit[5:4] foc_acc_x
+ * bit[3:2] foc_acc_y
+ * bit[1:0] foc_acc_z
+ */
+/* 0x6A CONF
+ * bit[7:2] (reserved)
+ * bit[1] nvm_prog_en
+ * bit[0] (reserved)
+ */
+/* 0x6B IF_CONF
+ * bit[7:6] (reserved)
+ * bit[5:4] if_mode
+ * bit[3:1] (reserved)
+ * bit[0] spi3
+ */
+/* 0x6C PMU_TRIGGER
+ * bit[7] (reserved)
+ * bit[6] wakeup_int
+ * bit[5] gyr_sleep_state
+ * bit[4:3] gyr_wakeup_trigger
+ * bit[2:0] gyr_sleep_trigger
+ */
+/* 0x6D SELF_TEST
+ * bit[7:5] (reserved)
+ * bit[4] gyr_self_test_enable
+ * bit[3] acc_self_test_amp
+ * bit[2] acc_self_test_sign
+ * bit[1:0] acc_self_test_enable
+ */
+/* 0x70 NV_CONF
+ * bit[7:4] (reserved)
+ * bit[3] u_spare_0
+ * bit[2] i2c_wdt_en
+ * bit[1] i2c_wdt_sel
+ * bit[0] i2c_spi_en
+ */
+/* 0x71 OFFSET_0 bit[7:0] off_acc_x */
+/* 0x72 OFFSET_1 bit[7:0] off_acc_y */
+/* 0x73 OFFSET_2 bit[7:0] off_acc_z */
+/* 0x74 OFFSET_3 bit[7:0] off_gyr_x_7_0 */
+/* 0x75 OFFSET_4 bit[7:0] off_gyr_y_7_0 */
+/* 0x76 OFFSET_5 bit[7:0] off_gyr_z_7_0 */
+/* 0x77 OFFSET_6
+ * bit[7] gyr_off_en
+ * bit[6] acc_off_en
+ * bit[5:4] off_gyr_Z_9_8
+ * bit[3:2] off_gyr_y_9_8
+ * bit[1:0] off_gyr_x_9_8
+ */
+/* 0x78 STEP_CNT_0 bit[7:0] step_cnt_7_0 */
+/* 0x79 STEP_CNT_1 bit[7:0] step_cnt_15_8 */
+/* 0x7A STEP_CONF_0 reset value = 0x15
+ * bit[7:5] (alpha)
+ * bit[4:3] min_threshold
+ * bit[2:0] steptime_min
+ */
+/* 0x7B STEP_CONF_1 reset value = 0x03
+ * bit[7:4] (reserved)
+ * bit[3] step_cnt_en
+ * bit[2:0] min_step_buf
+ */
+/* 0x7E CMD bit[7:0] cmd */
+
+
+
+
+BMI160::BMI160(PinName sda, PinName scl, int addr)
+{
+ m_i2c = new I2C(sda, scl) ;
+ m_addr = (addr << 1) ;
+ m_spi = 0 ;
+ m_cs = 0 ;
+ init() ;
+}
+
+BMI160::BMI160(PinName sck, PinName miso, PinName mosi, PinName cs)
+{
+ m_cs = new DigitalOut(cs, 1) ;
+ m_spi = new SPI(mosi, miso, sck) ;
+ m_spi->format(8, 3) ;
+ m_i2c = 0 ;
+ m_addr = 0 ;
+ init() ;
+}
+
+BMI160::~BMI160()
+{
+ if (m_spi) {
+ delete m_spi ;
+ delete m_cs ;
+ }
+ if (m_i2c) {
+ delete m_i2c ;
+ m_addr = 0 ;
+ }
+}
+
+void BMI160::i2c_readRegs(int addr, uint8_t *data, int len)
+{
+ char t[1] = {addr} ;
+ m_i2c->write(m_addr, t, 1, true) ;
+ m_i2c->read(m_addr, (char*)data, len) ;
+}
+
+void BMI160::i2c_writeRegs(uint8_t *data, int len)
+{
+ m_i2c->write(m_addr, (char *)data, len) ;
+}
+
+void BMI160::spi_readRegs(int addr, uint8_t *data, int len)
+{
+ *m_cs = 0 ;
+ m_spi->write(addr | 0x80) ;
+ for (int i = 0 ; i < len ; i++ ) {
+ data[i] = m_spi->write((addr+i)|0x80) ;
+ }
+ m_spi->write(0x00) ; // to terminate read mode
+ *m_cs = 1 ;
+}
+
+void BMI160::spi_writeRegs(uint8_t *data, int len)
+{
+ *m_cs = 0 ;
+ for (int i = 0 ; i < len-1 ; i++ ) {
+ m_spi->write((data[0]+i)^0x80) ; /* register address */
+ m_spi->write(data[i+1]) ; /* data to write */
+
+ }
+ *m_cs = 1 ;
+}
+
+void BMI160::readRegs(int addr, uint8_t *data, int len)
+{
+ if (m_spi) {
+ spi_readRegs(addr, data, len) ;
+ } else if (m_i2c) {
+ i2c_readRegs(addr, data, len) ;
+ }
+}
+
+void BMI160::writeRegs(uint8_t *data, int len)
+{
+ if (m_spi) {
+ spi_writeRegs(data, len) ;
+ } else if (m_i2c) {
+ i2c_writeRegs(data, len) ;
+ }
+}
+
+void BMI160::init(void)
+{
+}
+
+uint8_t BMI160::getChipID(void)
+{
+ uint8_t data ;
+ readRegs(REG_CHIP_ID, &data, 1) ;
+ return( data ) ;
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/BMI160.h Fri Aug 25 05:07:26 2017 +0000
@@ -0,0 +1,46 @@
+#ifndef _BMI160_H_
+#define _BMI160_H_
+class BMI160 {
+public:
+ /**
+ * BMI160 I2C Interface
+ *
+ * @param sda SDA pin
+ * @param scl SCL pin
+ * @param addr address of the I2C peripheral
+ */
+ BMI160(PinName sda, PinName scl, int addr) ;
+
+ /**
+ * BMI160 SPI Interface
+ *
+ * @param sck SPI SCKL pin
+ * @param miso SPI Master In Slave Out pin
+ * @param mosi SPI Master Out Slave In pin
+ * @param cs SPI Chip Select pin
+ */
+ BMI160(PinName sck, PinName miso, PinName mosi, PinName cs) ;
+
+/**
+ * BMI160 destructor
+ */
+ ~BMI160() ;
+
+ uint8_t getChipID(void) ;
+
+private:
+ SPI *m_spi ;
+ I2C *m_i2c ;
+ DigitalOut *m_cs ;
+ int m_addr ;
+
+ void init(void) ;
+ void i2c_readRegs(int addr, uint8_t *data, int len) ;
+ void i2c_writeRegs(uint8_t *data, int len) ;
+ void spi_readRegs(int addr, uint8_t *data, int len) ;
+ void spi_writeRegs(uint8_t *data, int len) ;
+ void readRegs(int addr, uint8_t *data, int len) ;
+ void writeRegs(uint8_t *data, int len) ;
+} ;
+
+#endif /* _BMI160_H_ */
\ No newline at end of file