Library to use BMX055 via I2C

Dependents:   NineIMUAttitude_MadgwickFilter

Revision:
0:be73a6efa20b
diff -r 000000000000 -r be73a6efa20b BMX055.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/BMX055.cpp	Fri Aug 21 03:11:36 2020 +0000
@@ -0,0 +1,135 @@
+#include "BMX055.hpp"
+
+void BMX055::Init_I2C(PinName arg_SDA, PinName arg_SCL)
+{
+    i2c = new I2C(arg_SDA, arg_SCL);
+    i2c->frequency(400000);//BMX055 MAX I2C Speed is 400kHz
+    char cmd[2];
+    
+    // Accelerometer initialization
+    cmd[0] = 0x0f; // Select PMU_Range register
+    cmd[1] = 0x03; // Range = +/- 2g
+    i2c->write(m_addr_acc, cmd, 2);
+    wait_ms(100);
+    
+    cmd[0] = 0x10; // Select PMU_BW register
+    cmd[1] = 0xff; // Bandwidth = 1000 Hz
+    i2c->write(m_addr_acc, cmd, 2);
+    wait_ms(100);
+    
+    cmd[0] = 0x11; // Select PMU_LPW register
+    cmd[1] = 0x00; // Normal mode, Sleep duration = 0.5ms
+    i2c->write(m_addr_acc, cmd, 2);
+    wait_ms(100);
+    
+    cmd[0] = 0x3e; // Select FIFO_CONFIG_1 register
+    cmd[1] = 0x00; // BYPASS mode, The mode a frame has X-Y-Z data (6bytes)
+    i2c->write(m_addr_acc, cmd, 2);
+    wait_ms(100);
+
+
+    // gyrometer initialization
+    cmd[0] = 0x0f;  // Select Range register
+    //cmd[1] = 0x04;  // Full scale = +/- 125 degree/s 3.8 m deg/s/LSB
+    cmd[1] = 0x02;  // Full scale = +/- 500 degree/s; 15.3 m deg/s/LSB
+    i2c->write(m_addr_gyr, cmd, 2);
+    wait_ms(100);
+    
+    cmd[0] = 0x10;  // Select Bandwidth register
+    cmd[1] = 0x02;  // ODR = 1000 Hz
+    i2c->write(m_addr_gyr, cmd, 2);
+    wait_ms(100);
+    
+    cmd[0] = 0x11;  // Select LPM1 register
+    cmd[1] = 0x00;  // Normal mode, Sleep duration = 2ms
+    i2c->write(m_addr_gyr, cmd, 2);
+    wait_ms(100);
+    
+    cmd[0] = 0x3e; // Select FIFO_CONFIG_1 register
+    cmd[1] = 0x00; // BYPASS mode, The mode a frame has XYZ data + stata (8bytes)
+    i2c->write(m_addr_gyr, cmd, 2);
+    wait_ms(100);
+
+
+    // magnetic sensor initialization
+    cmd[0] = 0x4b;  // Select Mag register
+    cmd[1] = 0x83;  // Soft reset
+    i2c->write(m_addr_mag, cmd, 2);
+    wait_ms(100);
+    cmd[0] = 0x4B;  // Select Mag register
+    cmd[1] = 0x01;  // Soft reset
+    i2c->write(m_addr_mag, cmd, 2);
+    wait_ms(100);
+    cmd[0] = 0x4c;  // Select Mag register
+    cmd[1] = 0x00;  // Normal Mode, Output Data Rate = 10 Hz
+    i2c->write(m_addr_mag, cmd, 2);
+    wait_ms(100);
+    cmd[0] = 0x4e;  // Select Mag register
+    cmd[1] = 0x84;  // X, Y, Z-Axis enabled
+    i2c->write(m_addr_mag, cmd, 2);
+    wait_ms(100);
+    cmd[0] = 0x51;  // Select Mag register
+    cmd[1] = 0x04;  // No. of Repetitions for X-Y Axis = 9
+    i2c->write(m_addr_mag, cmd, 2);
+    wait_ms(100);
+    cmd[0] = 0x52;  // Select Mag register
+    cmd[1] = 0x16;  // No. of Repetitions for Z-Axis = 15
+    i2c->write(m_addr_mag, cmd, 2);
+    wait_ms(100);
+}
+
+
+void BMX055::UpdateIMU()
+{
+    static char data_acc[6] = {0,0,0,0,0,0};
+    static char data_gyr[8] = {0,0,0,0,0,0,0,0};
+    
+    // Request Read out from FIFO buff
+    char reg = 0x3f;
+    i2c->write(m_addr_acc, &reg, 1);// Select data_acc register
+    //  - Read out 6 bytes of data_acc X-Y-Z frame
+    //  - FRAME:
+    //  [xAccl lsb | xAccl msb | yAccl lsb | yAccl msb | zAccl lsb | zAccl msb]
+    i2c->read(m_addr_acc, data_acc, 6);
+    
+    i2c->write(m_addr_gyr, &reg, 1);// Select data_acc register
+    //  - Read 6 bytes out of a frame which contain 8 bytes
+    //  - FRAME:
+    //  [xGyro lsb | xGyro msb | yGyro lsb | yGyro msb | zGyro lsb | zGyro msb | 
+    //    status-0 | status-1  ]
+    //  - Discurding the frame it takes 1.5us 
+    //      but it is less than reading 2 bytes via I2C
+    i2c->read(m_addr_gyr, data_gyr, 8);
+    
+    // Convert the data_acc to 12-bits
+    //  top 4 bits should be same (Two's complement)
+    acc.x = (signed short)(((unsigned short)data_acc[1] << 8) | (unsigned short)(data_acc[0] & 0xf0)) >> 4;
+    acc.y = (signed short)(((unsigned short)data_acc[3] << 8) | (unsigned short)(data_acc[2] & 0xf0)) >> 4;
+    acc.z = (signed short)(((unsigned short)data_acc[5] << 8) | (unsigned short)(data_acc[4] & 0xf0)) >> 4;
+    // Convert the data_gyr to 16-bits
+    gyr.x = (signed short)(((unsigned short)data_gyr[1] << 8) | (unsigned short)data_gyr[0]);
+    gyr.y = (signed short)(((unsigned short)data_gyr[3] << 8) | (unsigned short)data_gyr[2]);
+    gyr.z = (signed short)(((unsigned short)data_gyr[5] << 8) | (unsigned short)data_gyr[4]);
+}
+
+void BMX055::Update()
+{
+    UpdateIMU();
+    
+    char buf;
+    unsigned short data_mag[8];
+    for (int i = 0; i < 8; i++) {
+        char reg = 0x42 + i;
+        i2c->write(m_addr_mag, &reg, 1);// Select data register
+        // Read 8 bytes of data
+        // xMag lsb, xMag msb, yMag lsb, yMag msb, zMag lsb, zMag msb
+        // + 2 bytes for control bits
+        i2c->read(m_addr_mag, &buf, 1);// Request 1 byte of data
+        data_mag[i] = (unsigned char)buf;
+    }
+
+    // Convert the data
+    mag.x = ((signed short)((data_mag[1] << 8) | data_mag[0])) >> 3;
+    mag.y = ((signed short)((data_mag[3] << 8) | data_mag[2])) >> 3;
+    mag.z = ((signed short)((data_mag[5] << 8) | data_mag[4])) >> 1;
+}
\ No newline at end of file